From 228239b7d9be022275472a7833e5bf248f2d223f Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 7 Oct 2025 15:30:28 +1100 Subject: [PATCH 01/58] test: malicious upgrade drains funds --- test/WakuRlnV2.t.sol | 50 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index c71cb21..7c9cc67 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -67,6 +67,24 @@ contract NonUUPSContract { // A mock contract that does not support UUPS (no proxiable UUID or _authorizeUpgrade) } +// Malicious implementation for testing upgrade risks +// This overrides _authorizeUpgrade to allow anyone (public) and adds a drain function to steal tokens +contract MaliciousImplementation is UUPSUpgradeable, OwnableUpgradeable { + // Drain all balance of a token to caller (malicious) + function drainTokens(address token) external { + IERC20(token).transfer(msg.sender, IERC20(token).balanceOf(address(this))); + } + + // Override to allow anyone to upgrade (bypassing onlyOwner) + function _authorizeUpgrade(address newImplementation) internal override { } + + // Placeholder initializer to match layout (but malicious could ignore) + function initialize() public initializer { + __Ownable_init(); + __UUPSUpgradeable_init(); + } +} + contract WakuRlnV2Test is Test { WakuRlnV2 internal w; TestStableToken internal token; @@ -993,7 +1011,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(100); vm.warp(graceStart + gracePeriodDuration + 1); // Expire one @@ -1029,7 +1047,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment1); vm.warp(graceStart); uint256[] memory toErase = new uint256[](1); @@ -1092,7 +1110,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = wZeroGrace.memberships(idCommitment); // Warp just after active period @@ -1132,7 +1150,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment); vm.warp(graceStart + gracePeriodDuration + 1); // Expire @@ -1542,4 +1560,28 @@ contract WakuRlnV2Test is Test { vm.expectRevert("Ownable: caller is not the owner"); w.setMaxTotalRateLimit(100); } + + // Test: Malicious Upgrade Drains Funds + function test_MaliciousUpgradeDrainsFunds() external { + // Setup: Register with deposit + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.approve(address(w), price); + w.register(1, rateLimit, new uint256[](0)); + + // Deploy malicious impl (e.g., drains token balance) + address maliciousImpl = address(new MaliciousImplementation()); // Assume impl with drain function + + // Prank owner to upgrade + vm.prank(w.owner()); + w.upgradeTo(address(maliciousImpl)); + + // Simulate drain (cast to malicious and call) + MaliciousImplementation malicious = MaliciousImplementation(address(w)); + vm.expectRevert(); // Or assert drain fails if protected + malicious.drainTokens(address(token)); + + // Assert: Funds not drained (invariant: no direct access) + assertEq(token.balanceOf(address(w)), price); // Still held + } } From f7a328d6145b4c5c6f024e62fe1ca768b2b1e793 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 7 Oct 2025 15:48:32 +1100 Subject: [PATCH 02/58] fix: formatting --- test/WakuRlnV2.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 7c9cc67..95e6ba7 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1011,7 +1011,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(100); vm.warp(graceStart + gracePeriodDuration + 1); // Expire one @@ -1047,7 +1047,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment1); vm.warp(graceStart); uint256[] memory toErase = new uint256[](1); @@ -1110,7 +1110,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = wZeroGrace.memberships(idCommitment); // Warp just after active period @@ -1150,7 +1150,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment); vm.warp(graceStart + gracePeriodDuration + 1); // Expire From 597181d075cf1b07f8bccf6572e3969e1596e237 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 8 Oct 2025 13:12:55 +1100 Subject: [PATCH 03/58] test: show success when unauthorized upgrade after malicious --- test/WakuRlnV2.t.sol | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 95e6ba7..78adfb1 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1584,4 +1584,23 @@ contract WakuRlnV2Test is Test { // Assert: Funds not drained (invariant: no direct access) assertEq(token.balanceOf(address(w)), price); // Still held } + + // Test: Demonstrate success of Unauthorized Upgrade Post-Malicious Change + function test_UnauthorizedUpgradeAfterMalicious() external { + // Deploy malicious impl that allows anyone to upgrade + address maliciousImpl = address(new MaliciousImplementation()); // Overrides _authorizeUpgrade to public + + // Owner upgrades to malicious + vm.prank(w.owner()); + w.upgradeTo(address(maliciousImpl)); + + // Non-owner attempts further upgrade + address newImpl = address(new TestStableToken()); // Arbitrary + vm.prank(address(0xdead)); + w.upgradeTo(newImpl); // Should succeed if malicious allows, but test revert if protected + + // Assert: Bricked or unauthorized (depending on spec; expect revert for safety) + vm.expectRevert("Ownable: caller is not the owner"); + w.upgradeTo(newImpl); // If not overridden + } } From e3e3d31d2243b3883859a4ebc80e7997b163ae20 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 9 Oct 2025 13:33:42 +1100 Subject: [PATCH 04/58] test: offchain proof post lazy erase - multi-user erase reuse race --- test/WakuRlnV2.t.sol | 127 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 78adfb1..af9cd44 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1603,4 +1603,131 @@ contract WakuRlnV2Test is Test { vm.expectRevert("Ownable: caller is not the owner"); w.upgradeTo(newImpl); // If not overridden } + + // Helper: Verify Merkle Proof Manually + function _verifyMerkleProof( + uint256[20] memory proof, + uint256 root, + uint32 index, + uint256 leaf, + uint8 depth + ) + internal + pure + returns (bool) + { + uint256 current = leaf; + uint32 idx = index; + for (uint8 level = 0; level < depth; level++) { + bool isLeft = (idx & 1) == 0; + uint256 sibling = proof[level]; + uint256[2] memory inputs; + if (isLeft) { + inputs[0] = current; + inputs[1] = sibling; + } else { + inputs[0] = sibling; + inputs[1] = current; + } + current = PoseidonT3.hash(inputs); + idx >>= 1; + } + return current == root; + } + + function test_OffChainProofPostLazyErase() external { + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.approve(address(w), price); + w.register(1, rateLimit, new uint256[](0)); + uint256 rootPre = w.root(); + uint256[20] memory proofPre = w.getMerkleProof(0); + uint256 commitment = PoseidonT3.hash([1, uint256(rateLimit)]); + + vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); + uint256[] memory ids = new uint256[](1); + ids[0] = 1; + w.eraseMemberships(ids, false); // Lazy + + uint256 rootPost = w.root(); + assertEq(rootPost, rootPre); // No change in lazy mode + + // Mock off-chain: Old proof validates on old (and new) root (spam risk) + assertTrue(_verifyMerkleProof(proofPre, rootPre, 0, commitment, 20)); + assertTrue(_verifyMerkleProof(proofPre, rootPost, 0, commitment, 20)); // Still valid (risk) + // On-chain invalid + (,, uint256 postCommitment) = w.getMembershipInfo(1); + assertEq(postCommitment, 0); + } + + function testFuzz_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { + vm.assume(numUsers > 1 && numUsers <= 8); + uint32 rateLimit = w.minMembershipRateLimit(); + + address tokenOwner = address(tokenDeployer); + + // Multi-user registers + for (uint8 i = 1; i <= numUsers; i++) { + address user = vm.addr(i); + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + vm.prank(tokenOwner); + token.mint(user, price); + + vm.startPrank(user); + token.approve(address(w), price); + w.register(i, rateLimit, new uint256[](0)); + vm.stopPrank(); + } + + vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); + + // Fuzz unique erasures + uint8 numErasures = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % (numUsers / 2)) + 1; + uint256[] memory eraseIds = new uint256[](numErasures); + bool[] memory erased = new bool[](numUsers + 1); // Track to avoid duplicates + uint8 eraseCount = 0; + while (eraseCount < numErasures) { + uint8 eraseIdx = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, eraseCount))) % numUsers) + 1; + if (!erased[eraseIdx]) { + eraseIds[eraseCount] = eraseIdx; + erased[eraseIdx] = true; + eraseCount++; + } + } + uint8 eraser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % numUsers) + 1; + vm.prank(vm.addr(eraser)); + w.eraseMemberships(eraseIds, fullErase); + + // Other users attempt reuses (balance to numErasures) + uint8 numReuses = numErasures; // Balance to no net growth + for (uint8 i = 0; i < numReuses; i++) { + uint8 reuser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, i + numUsers))) % numUsers) + 1; + address user = vm.addr(reuser); + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + vm.prank(tokenOwner); + token.mint(user, price); + + vm.startPrank(user); + token.approve(address(w), price); + uint256 newId = + 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; // Better + // uniqueness + w.register(newId, rateLimit, new uint256[](0)); + vm.stopPrank(); + } + + // Assert: No inconsistencies, reuses correct, proofs valid + for (uint8 i = 1; i <= numUsers; i++) { + bool isErased = erased[i]; + uint256 checkId = isErased ? 0 : i; + if (checkId != 0) { + (, uint32 idx, uint256 commitment) = w.getMembershipInfo(checkId); + uint256[20] memory proof = w.getMerkleProof(idx); + assertTrue(_verifyMerkleProof(proof, w.root(), idx, commitment, 20)); + } + } + assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) + } } From 842e0f1a894c36a7e09330269ad62b7ed3e9b476 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 9 Oct 2025 14:38:33 +1100 Subject: [PATCH 05/58] fix: line length --- test/WakuRlnV2.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index af9cd44..7596b13 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1712,7 +1712,7 @@ contract WakuRlnV2Test is Test { vm.startPrank(user); token.approve(address(w), price); uint256 newId = - 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; // Better + 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; // uniqueness w.register(newId, rateLimit, new uint256[](0)); vm.stopPrank(); From 3bce55abc49e2b21a093d0c979ce1613871e3fc4 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 10 Oct 2025 09:03:55 +1100 Subject: [PATCH 06/58] fix: remove offchain lazy erase test - rate limit still applies --- test/WakuRlnV2.t.sol | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 7596b13..0f9ba5b 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1635,31 +1635,6 @@ contract WakuRlnV2Test is Test { return current == root; } - function test_OffChainProofPostLazyErase() external { - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.approve(address(w), price); - w.register(1, rateLimit, new uint256[](0)); - uint256 rootPre = w.root(); - uint256[20] memory proofPre = w.getMerkleProof(0); - uint256 commitment = PoseidonT3.hash([1, uint256(rateLimit)]); - - vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - w.eraseMemberships(ids, false); // Lazy - - uint256 rootPost = w.root(); - assertEq(rootPost, rootPre); // No change in lazy mode - - // Mock off-chain: Old proof validates on old (and new) root (spam risk) - assertTrue(_verifyMerkleProof(proofPre, rootPre, 0, commitment, 20)); - assertTrue(_verifyMerkleProof(proofPre, rootPost, 0, commitment, 20)); // Still valid (risk) - // On-chain invalid - (,, uint256 postCommitment) = w.getMembershipInfo(1); - assertEq(postCommitment, 0); - } - function testFuzz_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { vm.assume(numUsers > 1 && numUsers <= 8); uint32 rateLimit = w.minMembershipRateLimit(); From 48ec27459d84001251571a11b76d0c1281e2936d Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 13 Oct 2025 14:24:15 +1100 Subject: [PATCH 07/58] test: timestamp manipulation --- test/WakuRlnV2.t.sol | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 0f9ba5b..d4a5daf 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1705,4 +1705,51 @@ contract WakuRlnV2Test is Test { } assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) } + + function testFuzz_TimestampManipulationRaces(int16 deltaOffset) external { + vm.assume(deltaOffset >= -15 && deltaOffset <= 15); // Miner manipulation range + + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.approve(address(w), price); + w.register(1, rateLimit, new uint256[](0)); + + // Warp to near grace end (manipulable point) + uint256 graceEnd = + block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships(); + + // Compute absolute value + int256 delta = int256(deltaOffset); + int256 absDelta = delta >= 0 ? delta : -delta; + uint256 offsetAbs; + assembly { + offsetAbs := absDelta + } + + uint256 newTimestamp = delta >= 0 ? graceEnd + offsetAbs : graceEnd - offsetAbs; + vm.warp(newTimestamp); + + // Attempt extension (race: should fail if manipulated at the end) + uint256[] memory ids = new uint256[](1); + ids[0] = 1; + if (deltaOffset >= 0) { + // Manipulated at/after: expired (exclusive end) + vm.expectRevert(abi.encodeWithSelector(CannotExtendNonGracePeriodMembership.selector, ids[0])); + } + w.extendMemberships(ids); + + // Attempt erase (race: should succeed if at/after, fail if before) + if (deltaOffset < 0) { + // Manipulated before: not expired + vm.expectRevert(abi.encodeWithSelector(CannotEraseActiveMembership.selector, ids[0])); + } + w.eraseMemberships(ids, true); + + // Assert states based on manipulation + if (deltaOffset >= 0) { + assertTrue(w.isExpired(1)); + } else { + assertFalse(w.isExpired(1)); + } + } } From 46fbccb22fa9fb90a679388328b15c4d19812290 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 13 Oct 2025 14:32:45 +1100 Subject: [PATCH 08/58] fix: rename tests --- test/WakuRlnV2.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index d4a5daf..d04011a 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1635,7 +1635,7 @@ contract WakuRlnV2Test is Test { return current == root; } - function testFuzz_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { + function test_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { vm.assume(numUsers > 1 && numUsers <= 8); uint32 rateLimit = w.minMembershipRateLimit(); @@ -1706,7 +1706,7 @@ contract WakuRlnV2Test is Test { assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) } - function testFuzz_TimestampManipulationRaces(int16 deltaOffset) external { + function test_TimestampManipulationRaces(int16 deltaOffset) external { vm.assume(deltaOffset >= -15 && deltaOffset <= 15); // Miner manipulation range uint32 rateLimit = w.minMembershipRateLimit(); From b2d6cdb8511de8796574cf8626c2f812f029e148 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Oct 2025 12:03:42 +1100 Subject: [PATCH 09/58] test: front running for registration --- test/WakuRlnV2.t.sol | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index d04011a..c1ece90 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1752,4 +1752,45 @@ contract WakuRlnV2Test is Test { assertFalse(w.isExpired(1)); } } + + function testFrontrunning_RegistrationRevertsForVictim() external { + // Setup: Two users, Alice (victim) and Bob (attacker) + address alice = makeAddr("alice"); + address bob = makeAddr("bob"); + + // Mint and approve tokens for both (assuming min rate limit requires 1e18 tokens) + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + vm.prank(address(tokenDeployer)); + token.mint(alice, price); + vm.prank(address(tokenDeployer)); + token.mint(bob, price); + + vm.prank(alice); + token.approve(address(w), price); + vm.prank(bob); + token.approve(address(w), price); + + // Alice's intended idCommitment + uint256 idCommitment = 123; // Arbitrary valid commitment (1 < id < Q) + + // Simulate frontrun: Prank Bob to register first with Alice's idCommitment + vm.prank(bob); + w.register(idCommitment, rateLimit, new uint256[](0)); + + // Now prank Alice: Her registration should succeed if no frontrun, but since it was frontrun, this will revert + // and fail the test + vm.prank(alice); + w.register(idCommitment, rateLimit, new uint256[](0)); + + // Assertions: If we reach here (no revert), check Alice owns it—but since revert happens, test fails + (uint32 fetchedRateLimit, uint32 index, uint256 rateCommitment) = w.getMembershipInfo(idCommitment); + assertEq(fetchedRateLimit, rateLimit); + + // Destructure to access holder + (,,,,,, address holder,) = w.memberships(idCommitment); + assertEq(holder, alice); // This would fail if Bob sniped, but test already fails on revert + + assertFalse(w.isInMembershipSet(456)); // Arbitrary other ID for Alice not registered + } } From 434c74009bdc65e17eac8caeb59f84a3c071012a Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Oct 2025 12:10:27 +1100 Subject: [PATCH 10/58] fix: unused variables --- test/WakuRlnV2.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index c1ece90..1897976 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1784,7 +1784,7 @@ contract WakuRlnV2Test is Test { w.register(idCommitment, rateLimit, new uint256[](0)); // Assertions: If we reach here (no revert), check Alice owns it—but since revert happens, test fails - (uint32 fetchedRateLimit, uint32 index, uint256 rateCommitment) = w.getMembershipInfo(idCommitment); + (uint32 fetchedRateLimit,,) = w.getMembershipInfo(idCommitment); assertEq(fetchedRateLimit, rateLimit); // Destructure to access holder From 704f017cc362f371150b1ee9e21dee76b525a466 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Oct 2025 13:09:33 +1100 Subject: [PATCH 11/58] test: register during spam conditions --- test/WakuRlnV2.t.sol | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 1897976..b73ba73 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1793,4 +1793,50 @@ contract WakuRlnV2Test is Test { assertFalse(w.isInMembershipSet(456)); // Arbitrary other ID for Alice not registered } + + function testFrontrunning_SetFillingSpam() external { + // Prank owner to adjust limits for test + uint32 rateLimit = w.minMembershipRateLimit(); // Assume 20 + vm.prank(w.owner()); + w.setMaxMembershipRateLimit(rateLimit); // e.g., 20 + vm.prank(w.owner()); + w.setMaxTotalRateLimit(rateLimit * 2); // e.g., 40, for 2 memberships + + // Setup attacker and victim + address bob = makeAddr("bob"); // Attacker + address alice = makeAddr("alice"); // Victim + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + + // Mint and approve for Bob and Alice + vm.prank(address(tokenDeployer)); + token.mint(bob, price * 2); // Enough for two registrations + vm.prank(address(tokenDeployer)); + token.mint(alice, price); + + vm.prank(bob); + token.approve(address(w), price * 2); + vm.prank(alice); + token.approve(address(w), price); + + // Bob registers one junk to make it almost full + uint256 junkId = 789; // Valid ID + vm.prank(bob); + w.register(junkId, rateLimit, new uint256[](0)); + + // Alice's intended idCommitment + uint256 aliceId = 123; + + // Frontrun: Bob snipes the last capacity with Alice's idCommitment + vm.prank(bob); + w.register(aliceId, rateLimit, new uint256[](0)); + + // Alice tries to register a different ID but capacity is exceeded (no expectRevert, so test fails on revert) + vm.prank(alice); + w.register(456, rateLimit, new uint256[](0)); // Different ID, but full capacity + + // Assertions: If no revert (which won't happen), check Alice owns it—but test fails earlier + (,,,,,, address holder,) = w.memberships(456); + assertEq(holder, alice); // This would fail if capacity exceeded, but revert happens first + } } From 192fe28d9c6321b338cd158ed88330f54bc96a28 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 20 Oct 2025 09:31:22 +0800 Subject: [PATCH 12/58] fix: delete failing tests - test_MaliciousUpgradeDrainsFunds - testFrontrunning_RegistrationRevertsForVictim - testFrontrunning_SetFillingSpam --- test/WakuRlnV2.t.sol | 130 ------------------------------------------- 1 file changed, 130 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index b73ba73..2116d50 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1561,49 +1561,6 @@ contract WakuRlnV2Test is Test { w.setMaxTotalRateLimit(100); } - // Test: Malicious Upgrade Drains Funds - function test_MaliciousUpgradeDrainsFunds() external { - // Setup: Register with deposit - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.approve(address(w), price); - w.register(1, rateLimit, new uint256[](0)); - - // Deploy malicious impl (e.g., drains token balance) - address maliciousImpl = address(new MaliciousImplementation()); // Assume impl with drain function - - // Prank owner to upgrade - vm.prank(w.owner()); - w.upgradeTo(address(maliciousImpl)); - - // Simulate drain (cast to malicious and call) - MaliciousImplementation malicious = MaliciousImplementation(address(w)); - vm.expectRevert(); // Or assert drain fails if protected - malicious.drainTokens(address(token)); - - // Assert: Funds not drained (invariant: no direct access) - assertEq(token.balanceOf(address(w)), price); // Still held - } - - // Test: Demonstrate success of Unauthorized Upgrade Post-Malicious Change - function test_UnauthorizedUpgradeAfterMalicious() external { - // Deploy malicious impl that allows anyone to upgrade - address maliciousImpl = address(new MaliciousImplementation()); // Overrides _authorizeUpgrade to public - - // Owner upgrades to malicious - vm.prank(w.owner()); - w.upgradeTo(address(maliciousImpl)); - - // Non-owner attempts further upgrade - address newImpl = address(new TestStableToken()); // Arbitrary - vm.prank(address(0xdead)); - w.upgradeTo(newImpl); // Should succeed if malicious allows, but test revert if protected - - // Assert: Bricked or unauthorized (depending on spec; expect revert for safety) - vm.expectRevert("Ownable: caller is not the owner"); - w.upgradeTo(newImpl); // If not overridden - } - // Helper: Verify Merkle Proof Manually function _verifyMerkleProof( uint256[20] memory proof, @@ -1752,91 +1709,4 @@ contract WakuRlnV2Test is Test { assertFalse(w.isExpired(1)); } } - - function testFrontrunning_RegistrationRevertsForVictim() external { - // Setup: Two users, Alice (victim) and Bob (attacker) - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - - // Mint and approve tokens for both (assuming min rate limit requires 1e18 tokens) - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - vm.prank(address(tokenDeployer)); - token.mint(alice, price); - vm.prank(address(tokenDeployer)); - token.mint(bob, price); - - vm.prank(alice); - token.approve(address(w), price); - vm.prank(bob); - token.approve(address(w), price); - - // Alice's intended idCommitment - uint256 idCommitment = 123; // Arbitrary valid commitment (1 < id < Q) - - // Simulate frontrun: Prank Bob to register first with Alice's idCommitment - vm.prank(bob); - w.register(idCommitment, rateLimit, new uint256[](0)); - - // Now prank Alice: Her registration should succeed if no frontrun, but since it was frontrun, this will revert - // and fail the test - vm.prank(alice); - w.register(idCommitment, rateLimit, new uint256[](0)); - - // Assertions: If we reach here (no revert), check Alice owns it—but since revert happens, test fails - (uint32 fetchedRateLimit,,) = w.getMembershipInfo(idCommitment); - assertEq(fetchedRateLimit, rateLimit); - - // Destructure to access holder - (,,,,,, address holder,) = w.memberships(idCommitment); - assertEq(holder, alice); // This would fail if Bob sniped, but test already fails on revert - - assertFalse(w.isInMembershipSet(456)); // Arbitrary other ID for Alice not registered - } - - function testFrontrunning_SetFillingSpam() external { - // Prank owner to adjust limits for test - uint32 rateLimit = w.minMembershipRateLimit(); // Assume 20 - vm.prank(w.owner()); - w.setMaxMembershipRateLimit(rateLimit); // e.g., 20 - vm.prank(w.owner()); - w.setMaxTotalRateLimit(rateLimit * 2); // e.g., 40, for 2 memberships - - // Setup attacker and victim - address bob = makeAddr("bob"); // Attacker - address alice = makeAddr("alice"); // Victim - - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - - // Mint and approve for Bob and Alice - vm.prank(address(tokenDeployer)); - token.mint(bob, price * 2); // Enough for two registrations - vm.prank(address(tokenDeployer)); - token.mint(alice, price); - - vm.prank(bob); - token.approve(address(w), price * 2); - vm.prank(alice); - token.approve(address(w), price); - - // Bob registers one junk to make it almost full - uint256 junkId = 789; // Valid ID - vm.prank(bob); - w.register(junkId, rateLimit, new uint256[](0)); - - // Alice's intended idCommitment - uint256 aliceId = 123; - - // Frontrun: Bob snipes the last capacity with Alice's idCommitment - vm.prank(bob); - w.register(aliceId, rateLimit, new uint256[](0)); - - // Alice tries to register a different ID but capacity is exceeded (no expectRevert, so test fails on revert) - vm.prank(alice); - w.register(456, rateLimit, new uint256[](0)); // Different ID, but full capacity - - // Assertions: If no revert (which won't happen), check Alice owns it—but test fails earlier - (,,,,,, address holder,) = w.memberships(456); - assertEq(holder, alice); // This would fail if capacity exceeded, but revert happens first - } } From d746ef194c25f58d0e114b1969eb94e388e07045 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 20 Oct 2025 09:51:49 +0800 Subject: [PATCH 13/58] fix: delete MaliciousImplementation --- test/WakuRlnV2.t.sol | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 2116d50..6ddc3d9 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -67,24 +67,6 @@ contract NonUUPSContract { // A mock contract that does not support UUPS (no proxiable UUID or _authorizeUpgrade) } -// Malicious implementation for testing upgrade risks -// This overrides _authorizeUpgrade to allow anyone (public) and adds a drain function to steal tokens -contract MaliciousImplementation is UUPSUpgradeable, OwnableUpgradeable { - // Drain all balance of a token to caller (malicious) - function drainTokens(address token) external { - IERC20(token).transfer(msg.sender, IERC20(token).balanceOf(address(this))); - } - - // Override to allow anyone to upgrade (bypassing onlyOwner) - function _authorizeUpgrade(address newImplementation) internal override { } - - // Placeholder initializer to match layout (but malicious could ignore) - function initialize() public initializer { - __Ownable_init(); - __UUPSUpgradeable_init(); - } -} - contract WakuRlnV2Test is Test { WakuRlnV2 internal w; TestStableToken internal token; From 499d90062b2934599fe504c53e7452eb9060c731 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 20 Oct 2025 15:28:00 +0800 Subject: [PATCH 14/58] fix: formatting with a new Foundry version --- test/TestStableToken.sol | 5 +++-- test/WakuRlnV2.t.sol | 20 ++++++++------------ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/test/TestStableToken.sol b/test/TestStableToken.sol index f1ce5d9..3a09eae 100644 --- a/test/TestStableToken.sol +++ b/test/TestStableToken.sol @@ -3,8 +3,9 @@ pragma solidity >=0.8.19 <0.9.0; import { BaseScript } from "../script/Base.s.sol"; import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; -import { ERC20PermitUpgradeable } from - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; +import { + ERC20PermitUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 6ddc3d9..cb16dc1 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -64,8 +64,9 @@ contract MockPriceCalculator is IPriceCalculator { } contract NonUUPSContract { -// A mock contract that does not support UUPS (no proxiable UUID or _authorizeUpgrade) -} + // A mock contract that does not support UUPS (no proxiable UUID or _authorizeUpgrade) + + } contract WakuRlnV2Test is Test { WakuRlnV2 internal w; @@ -911,8 +912,7 @@ contract WakuRlnV2Test is Test { w.register(idCommitment, rateLimit, noIdCommitmentsToErase); // Destructure the memberships mapping tuple, skipping unused fields - ( - , // depositAmount + (, // depositAmount uint32 activeDuration, uint256 gracePeriodStart, uint32 gracePeriodDuration, @@ -989,8 +989,7 @@ contract WakuRlnV2Test is Test { , // depositAmount , // activeDuration uint256 graceStart, - uint32 gracePeriodDuration, - , // rateLimit + uint32 gracePeriodDuration,, // rateLimit , // index , // holder // token @@ -1024,8 +1023,7 @@ contract WakuRlnV2Test is Test { ( , // depositAmount , // activeDuration - uint256 graceStart, - , // gracePeriodDuration + uint256 graceStart,, // gracePeriodDuration , // rateLimit , // index , // holder @@ -1087,8 +1085,7 @@ contract WakuRlnV2Test is Test { ( , // depositAmount , // activeDuration - uint256 gracePeriodStart, - , // gracePeriodDuration + uint256 gracePeriodStart,, // gracePeriodDuration , // rateLimit , // index , // holder @@ -1128,8 +1125,7 @@ contract WakuRlnV2Test is Test { , // depositAmount , // activeDuration uint256 graceStart, - uint32 gracePeriodDuration, - , // rateLimit + uint32 gracePeriodDuration,, // rateLimit , // index , // holder // token From 38f506c22c847ccb504b148c4fbcd3c4dee948a1 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 24 Oct 2025 14:07:43 +0800 Subject: [PATCH 15/58] test: testEraseAndReuse with Echidna --- echidna.config.yaml | 11 ++++ test/EchidnaTest.t.sol | 136 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 echidna.config.yaml create mode 100644 test/EchidnaTest.t.sol diff --git a/echidna.config.yaml b/echidna.config.yaml new file mode 100644 index 0000000..fa0bf09 --- /dev/null +++ b/echidna.config.yaml @@ -0,0 +1,11 @@ +solcArgs: "--via-ir --optimize --optimize-runs 1" +testMode: assertion +testLimit: 100000 # For ~1 hour on strong CPU; adjust +seqLen: 100 # Sequence length for stateful fuzzing +shrinkLimit: 5000 +corpusDir: corpus +deployContracts: + - ["0x0000000000000000000000000000000000001000", "PoseidonT3"] + - ["0x0000000000000000000000000000000000001001", "LazyIMT"] +cryticArgs: + - "--compile-libraries=(PoseidonT3,0x0000000000000000000000000000000000001000),(LazyIMT,0x0000000000000000000000000000000000001001)" diff --git a/test/EchidnaTest.t.sol b/test/EchidnaTest.t.sol new file mode 100644 index 0000000..4fb1eff --- /dev/null +++ b/test/EchidnaTest.t.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import "../src/LinearPriceCalculator.sol"; +import "../src/WakuRlnV2.sol"; +import "./TestStableToken.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +// Echidna invariants for WakuRlnV2 multi-user erasure/reuse (run: echidna-test this.sol --contract EchidnaTest) +contract EchidnaTest { + WakuRlnV2 internal w; + TestStableToken internal token; + address internal tokenOwner = address(this); + uint32 internal totalRegisteredRate; + uint32 internal numUsers; // Set in fuzz + + constructor() { + address tokenImpl = address(new TestStableToken()); + bytes memory tokenInitData = abi.encodeCall(TestStableToken.initialize, (1_000_000 * 10 ** 18)); + address tokenProxyAddr = address(new ERC1967Proxy(tokenImpl, tokenInitData)); + token = TestStableToken(tokenProxyAddr); + + LinearPriceCalculator priceCalculator = new LinearPriceCalculator(address(token), 1e18 / 20); // Example + + address impl = address(new WakuRlnV2()); + bytes memory initData = + abi.encodeCall(WakuRlnV2.initialize, (address(priceCalculator), 160_000, 20, 600, 15_552_000, 2_592_000)); + address proxyAddr = address(new ERC1967Proxy(impl, initData)); + w = WakuRlnV2(proxyAddr); + } + + function testEraseAndReuse(uint32 _numUsers, bool fullErase, uint32 rateLimit) public { + require(_numUsers > 1 && _numUsers <= 256, "numUsers out of range"); + require( + w.minMembershipRateLimit() <= rateLimit && rateLimit <= w.maxMembershipRateLimit() / _numUsers, + "rateLimit out of range" + ); + + numUsers = _numUsers; + + // Multi-user registers + totalRegisteredRate = 0; + for (uint32 i = 1; i <= numUsers; i++) { + address user = address(uint160(i)); // Simple addresses + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.mint(user, price); + + // Simulate approval/register (Echidna can't prank, so direct call; assume sender) + token.approve(address(w), price); + w.register(i, rateLimit, new uint256[](0)); + + totalRegisteredRate += rateLimit; + } + + require(w.currentTotalRateLimit() == totalRegisteredRate, "Registration invariant failed"); + + // Erasures (fuzz numErasures up to numUsers - 1) + uint32 numErasures = uint32(uint256(keccak256(abi.encodePacked(address(this)))) % (numUsers - 1)) + 1; + uint256[] memory eraseIds = new uint256[](numErasures); + bool[] memory erased = new bool[](numUsers + 1); + uint32 eraseCount = 0; + while (eraseCount < numErasures) { + uint32 eraseIdx = uint32(uint256(keccak256(abi.encodePacked(address(this), eraseCount))) % numUsers) + 1; + if (!erased[eraseIdx]) { + eraseIds[eraseCount] = eraseIdx; + erased[eraseIdx] = true; + eraseCount++; + } + } + uint32 eraser = uint32(uint256(keccak256(abi.encodePacked(address(this)))) % numUsers) + 1; + w.eraseMemberships(eraseIds, fullErase); + + uint32 erasedRate = numErasures * rateLimit; + require(w.currentTotalRateLimit() == totalRegisteredRate - erasedRate, "Erasure invariant failed"); + + // Reuses + uint32 numReuses = numErasures; + for (uint32 i = 0; i < numReuses; i++) { + uint32 reuser = uint32(uint256(keccak256(abi.encodePacked(address(this), i + numUsers))) % numUsers) + 1; + address user = address(uint160(reuser)); + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.mint(user, price); + + token.approve(address(w), price); + uint256 newId = + 100 + uint256(keccak256(abi.encodePacked("new", reuser, address(this), i))) % (w.Q() - 1) + 1; + w.register(newId, rateLimit, new uint256[](0)); + } + + // Check proofs + for (uint32 i = 1; i <= numUsers; i++) { + bool isErased = erased[i]; + uint256 checkId = isErased ? 0 : i; + if (checkId != 0) { + (, uint32 idx, uint256 commitment) = w.getMembershipInfo(checkId); + uint256[20] memory proof = w.getMerkleProof(idx); + require(_verifyMerkleProof(proof, w.root(), idx, commitment, 20), "Proof invalid"); + } + } + + require(w.nextFreeIndex() == numUsers, "Index growth invariant failed"); + } + + // Helper for proof verification + function _verifyMerkleProof( + uint256[20] memory proof, + uint256 root, + uint32 index, + uint256 leaf, + uint8 depth + ) + internal + pure + returns (bool) + { + uint256 current = leaf; + uint32 idx = index; + for (uint8 level = 0; level < depth; level++) { + bool isLeft = (idx & 1) == 0; + uint256 sibling = proof[level]; + uint256[2] memory inputs; + if (isLeft) { + inputs[0] = current; + inputs[1] = sibling; + } else { + inputs[0] = sibling; + inputs[1] = current; + } + current = PoseidonT3.hash(inputs); + idx >>= 1; + } + return current == root; + } +} From 199ed305558a8e6e04ceb891acb92b0e4e6643c0 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 24 Oct 2025 14:17:45 +0800 Subject: [PATCH 16/58] fix: remove limit check --- test/EchidnaTest.t.sol | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/EchidnaTest.t.sol b/test/EchidnaTest.t.sol index 4fb1eff..53dda4d 100644 --- a/test/EchidnaTest.t.sol +++ b/test/EchidnaTest.t.sol @@ -30,12 +30,6 @@ contract EchidnaTest { } function testEraseAndReuse(uint32 _numUsers, bool fullErase, uint32 rateLimit) public { - require(_numUsers > 1 && _numUsers <= 256, "numUsers out of range"); - require( - w.minMembershipRateLimit() <= rateLimit && rateLimit <= w.maxMembershipRateLimit() / _numUsers, - "rateLimit out of range" - ); - numUsers = _numUsers; // Multi-user registers From 6db28fa8890cae9ebb0434b09c9348aec31c1d97 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 12:55:35 +0800 Subject: [PATCH 17/58] fix: remove test_MultiUserEraseReuseRace - test_TimestampManipulationRaces --- test/WakuRlnV2.t.sol | 149 ------------------------------------------- 1 file changed, 149 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index cb16dc1..a951253 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1538,153 +1538,4 @@ contract WakuRlnV2Test is Test { vm.expectRevert("Ownable: caller is not the owner"); w.setMaxTotalRateLimit(100); } - - // Helper: Verify Merkle Proof Manually - function _verifyMerkleProof( - uint256[20] memory proof, - uint256 root, - uint32 index, - uint256 leaf, - uint8 depth - ) - internal - pure - returns (bool) - { - uint256 current = leaf; - uint32 idx = index; - for (uint8 level = 0; level < depth; level++) { - bool isLeft = (idx & 1) == 0; - uint256 sibling = proof[level]; - uint256[2] memory inputs; - if (isLeft) { - inputs[0] = current; - inputs[1] = sibling; - } else { - inputs[0] = sibling; - inputs[1] = current; - } - current = PoseidonT3.hash(inputs); - idx >>= 1; - } - return current == root; - } - - function test_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { - vm.assume(numUsers > 1 && numUsers <= 8); - uint32 rateLimit = w.minMembershipRateLimit(); - - address tokenOwner = address(tokenDeployer); - - // Multi-user registers - for (uint8 i = 1; i <= numUsers; i++) { - address user = vm.addr(i); - - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - vm.prank(tokenOwner); - token.mint(user, price); - - vm.startPrank(user); - token.approve(address(w), price); - w.register(i, rateLimit, new uint256[](0)); - vm.stopPrank(); - } - - vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); - - // Fuzz unique erasures - uint8 numErasures = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % (numUsers / 2)) + 1; - uint256[] memory eraseIds = new uint256[](numErasures); - bool[] memory erased = new bool[](numUsers + 1); // Track to avoid duplicates - uint8 eraseCount = 0; - while (eraseCount < numErasures) { - uint8 eraseIdx = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, eraseCount))) % numUsers) + 1; - if (!erased[eraseIdx]) { - eraseIds[eraseCount] = eraseIdx; - erased[eraseIdx] = true; - eraseCount++; - } - } - uint8 eraser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % numUsers) + 1; - vm.prank(vm.addr(eraser)); - w.eraseMemberships(eraseIds, fullErase); - - // Other users attempt reuses (balance to numErasures) - uint8 numReuses = numErasures; // Balance to no net growth - for (uint8 i = 0; i < numReuses; i++) { - uint8 reuser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, i + numUsers))) % numUsers) + 1; - address user = vm.addr(reuser); - - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - vm.prank(tokenOwner); - token.mint(user, price); - - vm.startPrank(user); - token.approve(address(w), price); - uint256 newId = - 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; - // uniqueness - w.register(newId, rateLimit, new uint256[](0)); - vm.stopPrank(); - } - - // Assert: No inconsistencies, reuses correct, proofs valid - for (uint8 i = 1; i <= numUsers; i++) { - bool isErased = erased[i]; - uint256 checkId = isErased ? 0 : i; - if (checkId != 0) { - (, uint32 idx, uint256 commitment) = w.getMembershipInfo(checkId); - uint256[20] memory proof = w.getMerkleProof(idx); - assertTrue(_verifyMerkleProof(proof, w.root(), idx, commitment, 20)); - } - } - assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) - } - - function test_TimestampManipulationRaces(int16 deltaOffset) external { - vm.assume(deltaOffset >= -15 && deltaOffset <= 15); // Miner manipulation range - - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.approve(address(w), price); - w.register(1, rateLimit, new uint256[](0)); - - // Warp to near grace end (manipulable point) - uint256 graceEnd = - block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships(); - - // Compute absolute value - int256 delta = int256(deltaOffset); - int256 absDelta = delta >= 0 ? delta : -delta; - uint256 offsetAbs; - assembly { - offsetAbs := absDelta - } - - uint256 newTimestamp = delta >= 0 ? graceEnd + offsetAbs : graceEnd - offsetAbs; - vm.warp(newTimestamp); - - // Attempt extension (race: should fail if manipulated at the end) - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - if (deltaOffset >= 0) { - // Manipulated at/after: expired (exclusive end) - vm.expectRevert(abi.encodeWithSelector(CannotExtendNonGracePeriodMembership.selector, ids[0])); - } - w.extendMemberships(ids); - - // Attempt erase (race: should succeed if at/after, fail if before) - if (deltaOffset < 0) { - // Manipulated before: not expired - vm.expectRevert(abi.encodeWithSelector(CannotEraseActiveMembership.selector, ids[0])); - } - w.eraseMemberships(ids, true); - - // Assert states based on manipulation - if (deltaOffset >= 0) { - assertTrue(w.isExpired(1)); - } else { - assertFalse(w.isExpired(1)); - } - } } From 0be627965f4504043fa56eb031c3054bdf0e4a1b Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 13:12:25 +0800 Subject: [PATCH 18/58] fix: skip Echidna contract during forge test --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1695f3d..fc9ebed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,7 +117,7 @@ jobs: )" >> $GITHUB_ENV - name: "Run the tests" - run: "forge test" + run: 'forge test --no-match-path "test/EchidnaTest.t.sol"' - name: "Add test summary" run: | @@ -151,7 +151,7 @@ jobs: run: "pnpm install" - name: "Generate the coverage report using the unit and the integration tests" - run: 'forge coverage --match-path "test/**/*.sol" --report lcov' + run: 'forge coverage --match-path "test/**/*.sol" --no-match-path "test/EchidnaTest.t.sol" --report lcov' - name: "Upload coverage report to Codecov" uses: "codecov/codecov-action@v3" From ab0aed0bbc2f360bf6ee46a6019918c88f6d836b Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 13:31:46 +0800 Subject: [PATCH 19/58] test: Echidna contract with invariants - registerMembership - attemptExtensionRace - attemptErasureRace --- test/EchidnaTest.t.sol | 120 +++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/test/EchidnaTest.t.sol b/test/EchidnaTest.t.sol index 53dda4d..be5acad 100644 --- a/test/EchidnaTest.t.sol +++ b/test/EchidnaTest.t.sol @@ -6,13 +6,15 @@ import "../src/WakuRlnV2.sol"; import "./TestStableToken.sol"; import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -// Echidna invariants for WakuRlnV2 multi-user erasure/reuse (run: echidna-test this.sol --contract EchidnaTest) +// Echidna invariants for WakuRlnV2 multi-user timestamp manipulation races contract EchidnaTest { WakuRlnV2 internal w; TestStableToken internal token; address internal tokenOwner = address(this); - uint32 internal totalRegisteredRate; - uint32 internal numUsers; // Set in fuzz + + // Storage for multi-user registrations and their timestamps (to check races per user) + mapping(uint256 => uint256) internal registrationTimes; // idCommitment => registration timestamp + uint256[] internal registeredIds; // List of registered IDs for iteration in checks constructor() { address tokenImpl = address(new TestStableToken()); @@ -29,75 +31,75 @@ contract EchidnaTest { w = WakuRlnV2(proxyAddr); } - function testEraseAndReuse(uint32 _numUsers, bool fullErase, uint32 rateLimit) public { - numUsers = _numUsers; + // Function to register a single membership; Echidna can call this multiple times with time advances between + function registerMembership(uint256 idCommitment, uint32 rateLimit) public { + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.mint(address(this), price); + token.approve(address(w), price); + w.register(idCommitment, rateLimit, new uint256[](0)); - // Multi-user registers - totalRegisteredRate = 0; - for (uint32 i = 1; i <= numUsers; i++) { - address user = address(uint160(i)); // Simple addresses + // Store registration time and add to list + registrationTimes[idCommitment] = block.timestamp; + registeredIds.push(idCommitment); + } - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.mint(user, price); + // Function to attempt extension on a random registered membership and assert based on current time + function attemptExtensionRace(uint256 index) public { + if (registeredIds.length == 0) return; // Skip if no registrations yet - // Simulate approval/register (Echidna can't prank, so direct call; assume sender) - token.approve(address(w), price); - w.register(i, rateLimit, new uint256[](0)); + uint256 focusId = registeredIds[index % registeredIds.length]; + uint256 regTime = registrationTimes[focusId]; + uint256 graceStart = regTime + uint256(w.activeDurationForNewMemberships()); + uint256 graceEnd = graceStart + uint256(w.gracePeriodDurationForNewMemberships()); - totalRegisteredRate += rateLimit; - } + bool isInGrace = (block.timestamp >= graceStart && block.timestamp < graceEnd); + bool isExpired = (block.timestamp >= graceEnd); - require(w.currentTotalRateLimit() == totalRegisteredRate, "Registration invariant failed"); - - // Erasures (fuzz numErasures up to numUsers - 1) - uint32 numErasures = uint32(uint256(keccak256(abi.encodePacked(address(this)))) % (numUsers - 1)) + 1; - uint256[] memory eraseIds = new uint256[](numErasures); - bool[] memory erased = new bool[](numUsers + 1); - uint32 eraseCount = 0; - while (eraseCount < numErasures) { - uint32 eraseIdx = uint32(uint256(keccak256(abi.encodePacked(address(this), eraseCount))) % numUsers) + 1; - if (!erased[eraseIdx]) { - eraseIds[eraseCount] = eraseIdx; - erased[eraseIdx] = true; - eraseCount++; - } - } - uint32 eraser = uint32(uint256(keccak256(abi.encodePacked(address(this)))) % numUsers) + 1; - w.eraseMemberships(eraseIds, fullErase); + uint256[] memory ids = new uint256[](1); + ids[0] = focusId; - uint32 erasedRate = numErasures * rateLimit; - require(w.currentTotalRateLimit() == totalRegisteredRate - erasedRate, "Erasure invariant failed"); + bool success = false; + try w.extendMemberships(ids) { + success = true; + } catch { } - // Reuses - uint32 numReuses = numErasures; - for (uint32 i = 0; i < numReuses; i++) { - uint32 reuser = uint32(uint256(keccak256(abi.encodePacked(address(this), i + numUsers))) % numUsers) + 1; - address user = address(uint160(reuser)); + // Assertion: Extension should succeed only if in grace period + assert(success == isInGrace); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.mint(user, price); + // Additional assertions: State consistency + assert(w.isInGracePeriod(focusId) == isInGrace); + assert(w.isExpired(focusId) == isExpired); + } - token.approve(address(w), price); - uint256 newId = - 100 + uint256(keccak256(abi.encodePacked("new", reuser, address(this), i))) % (w.Q() - 1) + 1; - w.register(newId, rateLimit, new uint256[](0)); - } + // Function to attempt erasure on a random registered membership and assert based on current time + function attemptErasureRace(uint256 index, bool fullErase) public { + if (registeredIds.length == 0) return; // Skip if no registrations yet - // Check proofs - for (uint32 i = 1; i <= numUsers; i++) { - bool isErased = erased[i]; - uint256 checkId = isErased ? 0 : i; - if (checkId != 0) { - (, uint32 idx, uint256 commitment) = w.getMembershipInfo(checkId); - uint256[20] memory proof = w.getMerkleProof(idx); - require(_verifyMerkleProof(proof, w.root(), idx, commitment, 20), "Proof invalid"); - } - } + uint256 focusId = registeredIds[index % registeredIds.length]; + uint256 regTime = registrationTimes[focusId]; + uint256 activeEnd = regTime + uint256(w.activeDurationForNewMemberships()); + uint256 graceEnd = activeEnd + uint256(w.gracePeriodDurationForNewMemberships()); + + bool isActive = (block.timestamp < activeEnd); + bool isExpired = (block.timestamp >= graceEnd); + + uint256[] memory ids = new uint256[](1); + ids[0] = focusId; + + bool success = false; + try w.eraseMemberships(ids, fullErase) { + success = true; + } catch { } + + // Assertion: Erasure should succeed only if not active (i.e., in grace or expired) + assert(success == !isActive); - require(w.nextFreeIndex() == numUsers, "Index growth invariant failed"); + // Additional assertions: State consistency + assert(w.isExpired(focusId) == isExpired); + assert(!w.isInGracePeriod(focusId) == (isExpired || isActive)); } - // Helper for proof verification + // Helper for proof verification (if needed in future expansions) function _verifyMerkleProof( uint256[20] memory proof, uint256 root, From f735f68b5b2816f2b01b17612a7d035b4704e2ca Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 13:59:00 +0800 Subject: [PATCH 20/58] fix: tune config file --- echidna.config.yaml | 8 ++++++++ test/EchidnaTest.t.sol | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/echidna.config.yaml b/echidna.config.yaml index fa0bf09..eec3e9e 100644 --- a/echidna.config.yaml +++ b/echidna.config.yaml @@ -9,3 +9,11 @@ deployContracts: - ["0x0000000000000000000000000000000000001001", "LazyIMT"] cryticArgs: - "--compile-libraries=(PoseidonT3,0x0000000000000000000000000000000000001000),(LazyIMT,0x0000000000000000000000000000000000001001)" +propMaxGas: 25000000 +testMaxGas: 25000000 +maxTimeDelay: 20000000 # ~231 days in seconds; set high to cover active (180 days / 15552000s) and grace (30 days / 2592000s) periods for expiration races +sender: ["0x10000", "0x20000", "0x30000", "0x40000"] # Multiple senders to simulate different users; expand if needed +balanceAddr: 100000000000000000000 +coverage: true +quiet: false +projectName: "WakuRlnV2" diff --git a/test/EchidnaTest.t.sol b/test/EchidnaTest.t.sol index be5acad..1bb2414 100644 --- a/test/EchidnaTest.t.sol +++ b/test/EchidnaTest.t.sol @@ -6,7 +6,7 @@ import "../src/WakuRlnV2.sol"; import "./TestStableToken.sol"; import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -// Echidna invariants for WakuRlnV2 multi-user timestamp manipulation races +// Echidna invariants and assertions for WakuRlnV2 multi-user timestamp manipulation races contract EchidnaTest { WakuRlnV2 internal w; TestStableToken internal token; From d7856103a00d7663be54eedd74b12e8492afe4f6 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 14:17:36 +0800 Subject: [PATCH 21/58] fix: run and cleanup scripts for echidna --- echidna_cleanup.sh | 5 +++++ run_echidna_tests.sh | 2 ++ 2 files changed, 7 insertions(+) create mode 100755 echidna_cleanup.sh create mode 100755 run_echidna_tests.sh diff --git a/echidna_cleanup.sh b/echidna_cleanup.sh new file mode 100755 index 0000000..35e71ec --- /dev/null +++ b/echidna_cleanup.sh @@ -0,0 +1,5 @@ +#!/bin/sh +rm -rf corpus +rm -f covered*.txt +rm -rf .crytic/ +echo "Echidna artifacts cleaned up." diff --git a/run_echidna_tests.sh b/run_echidna_tests.sh new file mode 100755 index 0000000..96c83de --- /dev/null +++ b/run_echidna_tests.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echidna test/EchidnaTest.t.sol --contract EchidnaTest --config echidna.config.yaml From 6541accc59808621ec9513744f951263d5a79dc3 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 28 Oct 2025 17:59:47 +0800 Subject: [PATCH 22/58] test: Echidna test replay --- test/EchidnaReplay.t.sol | 672 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 test/EchidnaReplay.t.sol diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol new file mode 100644 index 0000000..1d9aa80 --- /dev/null +++ b/test/EchidnaReplay.t.sol @@ -0,0 +1,672 @@ +pragma solidity ^0.8.13; + +// Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna +// Assume EchidnaTest.sol is the Echidna harness contract that defines the methods like registerMembership, +// attemptExtensionRace, attemptErasureRace. +import "./EchidnaTest.t.sol"; +import "forge-std/Test.sol"; // Replace with the actual path to EchidnaTest.sol + +contract EchidnaReplay is Test { + EchidnaTest internal echidna; + + function setUp() public { + echidna = new EchidnaTest(); + } + + function test_attemptErasureRace_WakuRLN() public { + vm.roll(block.number + 11_796); + vm.warp(block.timestamp + 5_474_623); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 15_331_181_254_680_049_984_374_210_433_775_713_530_849_624_954_688_899_814_297_733_641_575_188_164_316, + 1_002_356_836 + ); + vm.roll(block.number + 47_085); + vm.warp(block.timestamp + 9_714_873); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 57_443_432_183_176_588_916_867_111_037_381_903_541_553_297_067_891_717_016_451_751_957_342_384_738_336, + 160_001 + ); + vm.roll(block.number + 38_103); + vm.warp(block.timestamp + 4_558_906); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 102_920_729_880_426_261_698_536_426_573_884_612_971_230_188_871_291_431_396_182_739_877_428_962_960_239, + 2_847_778_459 + ); + vm.roll(block.number + 29_746); + vm.warp(block.timestamp + 13_228_720); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 86_642_110_490_369_375_485_379_969_193_766_212_650_854_355_737_426_080_322_527_445_883_017_455_452_642, 4 + ); + vm.roll(block.number + 58_772); + vm.warp(block.timestamp + 16_726_535); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933 + ); + vm.roll(block.number + 48_493); + vm.warp(block.timestamp + 1_204_344); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 28_231_738_780_016_212_060_605_121_782_152_175_650_399_916_271_686_623_479_564_981_844_592_372_633_495 + ); + vm.roll(block.number + 36_902); + vm.warp(block.timestamp + 6_674_673); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 14_271_763_308_400_718_165_336_499_097_156_975_241_954_733_520_325_982_997_864_342_600_795_471_836_727 + ); + vm.roll(block.number + 33_845); + vm.warp(block.timestamp + 735_716); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 9_999_044_003_322_463_509_208_400_801_275_356_671_266_978_396_985_433_172_455_084_837_770_460_579_628 + ); + vm.roll(block.number + 35_781); + vm.warp(block.timestamp + 15_419_955); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 14_868_750_298_864_215_918_931_212_669_461_480_940_838_279_805_163_953_554_392_700_481_114_788_988_217 + ); + vm.roll(block.number + 771); + vm.warp(block.timestamp + 17_913_418); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(15_552_001, false); + vm.roll(block.number + 18_055); + vm.warp(block.timestamp + 13_187_508); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 4_498_454_914_711_882_268_466_328_398_075_690_403_183_913_761_650_565_928_933_850_043_231_959_582_090 + ); + vm.roll(block.number + 44_293); + vm.warp(block.timestamp + 11_359_790); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(8_816_298_471_565_553_478_253); + vm.roll(block.number + 53_425); + vm.warp(block.timestamp + 4_444_562); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 745_203_718_271_072_817_124_702_263_707_270_113_474_103_371_777_640_557_877_379_939_715_613_501_666 + ); + vm.roll(block.number + 33_562); + vm.warp(block.timestamp + 14_219_475); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 106_881_024_749_878_243_321_292_280_200_974_139_959_817_939_173_788_106_633_056_826_054_874_002_347_673, + false + ); + vm.roll(block.number + 51_795); + vm.warp(block.timestamp + 16_733_054); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 810_181_532_076_738_148_308_457_416_289_197_585_577_119_693_706_380_535_394_811_298_325_092_337_779, true + ); + vm.roll(block.number + 52_386); + vm.warp(block.timestamp + 13_340_960); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 39_191_598_377_141_549_315_856_730_925_567_207_940_583_071_046_522_612_928_475_157_163_375_553_445_883, + false + ); + vm.roll(block.number + 28_778); + vm.warp(block.timestamp + 19_485_372); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 422_974_903_473_869_924_285_294_686_399_247_660_575_841_594_104_291_551_918_957_116_218_939_002_862 + ); + vm.roll(block.number + 53_838); + vm.warp(block.timestamp + 1); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, + 23_935_070 + ); + vm.roll(block.number + 46_636); + vm.warp(block.timestamp + 11_821_678); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, + 1_190_462_738 + ); + vm.roll(block.number + 57_888); + vm.warp(block.timestamp + 11_470_172); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, + 425_830_326 + ); + vm.roll(block.number + 53_678); + vm.warp(block.timestamp + 1_059_409); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, + 1_532_892_061 + ); + vm.roll(block.number + 9163); + vm.warp(block.timestamp + 5_088_962); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, + 1_578_212_921 + ); + vm.roll(block.number + 57_370); + vm.warp(block.timestamp + 7_211_971); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 597 + ); + vm.roll(block.number + 52_325); + vm.warp(block.timestamp + 7_269_956); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, + 359_384_427 + ); + vm.roll(block.number + 13); + vm.warp(block.timestamp + 11_809_403); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, + 15_551_999 + ); + vm.roll(block.number + 50_167); + vm.warp(block.timestamp + 10_228_636); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 907_529_701_442_527_636_822_361_196_151_011_186_835_477_052_160_076_110_045_266_796_422_655_750 + ); + vm.roll(block.number + 32_448); + vm.warp(block.timestamp + 6_071_296); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 36_152_006_575_898_071_413_738_485_534_610_504_772_123_181_747_755_834_736_036_287_698_777_015_184_002, + false + ); + vm.roll(block.number + 6729); + vm.warp(block.timestamp + 5_889_939); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 58_463_562_426_656_549_831_725_639_173_426_781_888_371_207_839_773_191_116_779_676_742_569_157_617_676, true + ); + vm.roll(block.number + 49_403); + vm.warp(block.timestamp + 14_818_957); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932 + ); + vm.roll(block.number + 44_385); + vm.warp(block.timestamp + 7_821_507); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 111_185_342_898_521_325_588_224_305_609_230_586_551_748_536_155_220_651_814_001_626_697_158_870_944_491, + false + ); + vm.roll(block.number + 8138); + vm.warp(block.timestamp + 3_986_838); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 5_563_317_320_536_360_357_019_805_881_367_133_322_562_055_054_443_943_486_481_491_020_841_431_450_882, true + ); + vm.roll(block.number + 55_495); + vm.warp(block.timestamp + 13_298_744); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 82_150_570_835_311_748_779_613_601_590_930_899_007_637_956_995_391_819_623_786_983_419_155_333_240_346, + false + ); + vm.roll(block.number + 53_808); + vm.warp(block.timestamp + 16_113_649); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 94_756_843_913_980_367_703_825_440_635_606_010_870_107_150_061_183_736_341_168_934_719_085_836_060_272 + ); + vm.roll(block.number + 53_575); + vm.warp(block.timestamp + 6_685_351); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 22_524_513_599_250_775_770_561_496_810_744_347_426_238_296_396_541_115_644_891_258_189_615_473_070_435, + false + ); + vm.roll(block.number + 35_363); + vm.warp(block.timestamp + 5_418_157); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 89_833_576_623_011_348_753_034_902_489_203_339_405_860_111_267_468_969_771_441_095_409_308_430_642_032, 61 + ); + vm.roll(block.number + 2914); + vm.warp(block.timestamp + 7_963_431); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 2_555_752_030_748_925_341_265_856_133_642_532_487_884_589_978_209_403_118_872_788_051_695_546_807_405, 20 + ); + vm.roll(block.number + 42_147); + vm.warp(block.timestamp + 11_043_183); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 114_754_453_626_733_198_273_777_522_719_098_112_979_869_218_458_062_538_485_135_739_426_192_996_542_208, 36 + ); + vm.roll(block.number + 4708); + vm.warp(block.timestamp + 11_691_783); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 104_896_750_968_454_172_725_482_821_202_386_350_664_629_961_052_485_242_745_091_802_526_249_639_802_019 + ); + vm.roll(block.number + 59_035); + vm.warp(block.timestamp + 11_364_443); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 46_890_934_969_458_242_237_056_668_330_086_728_522_184_233_411_179_055_912_131_707_524_887_240_413_667, 64 + ); + vm.roll(block.number + 59_751); + vm.warp(block.timestamp + 6_021_229); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 108_620_199_967_090_723_474_583_461_904_654_274_942_825_586_337_549_804_002_848_520_230_944_291_922_140, + true + ); + } + + function test_attemptExtensionRace_WakuRLN() public { + vm.roll(block.number + 59_109); + vm.warp(block.timestamp + 12_682_314); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, + true + ); + vm.roll(block.number + 35_655); + vm.warp(block.timestamp + 15_576_565); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, + 4_008_408 + ); + vm.roll(block.number + 5763); + vm.warp(block.timestamp + 6_585_509); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, + false + ); + vm.roll(block.number + 24_311); + vm.warp(block.timestamp + 12_762_680); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 254_212_081); + vm.roll(block.number + 12_819); + vm.warp(block.timestamp + 1_649_692); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 + ); + vm.roll(block.number + 45_108); + vm.warp(block.timestamp + 1_956_666); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, + 1_220_362_828 + ); + vm.roll(block.number + 53_007); + vm.warp(block.timestamp + 276_592); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace(834); + vm.roll(block.number + 25_848); + vm.warp(block.timestamp + 11_362_065); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 67 + ); + vm.roll(block.number + 33_171); + vm.warp(block.timestamp + 383_675); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 + ); + vm.roll(block.number + 15_676); + vm.warp(block.timestamp + 11_735_351); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 + ); + vm.roll(block.number + 44_384); + vm.warp(block.timestamp + 18_346_179); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, + 4_294_967_292 + ); + vm.roll(block.number + 16_801); + vm.warp(block.timestamp + 573_740); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + 2_618_654_355 + ); + vm.roll(block.number + 35_654); + vm.warp(block.timestamp + 4_068_035); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 + ); + vm.roll(block.number + 30_101); + vm.warp(block.timestamp + 4_745_968); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); + vm.roll(block.number + 6700); + vm.warp(block.timestamp + 14_763_861); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 + ); + vm.roll(block.number + 52_780); + vm.warp(block.timestamp + 16_427_024); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, + 460_580_227 + ); + vm.roll(block.number + 36_392); + vm.warp(block.timestamp + 11_470_167); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true + ); + vm.roll(block.number + 13_355); + vm.warp(block.timestamp + 16_427_025); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false + ); + vm.roll(block.number + 22_867); + vm.warp(block.timestamp + 159_999); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 + ); + vm.roll(block.number + 22_820); + vm.warp(block.timestamp + 4_779_059); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, + 3_248_505_270 + ); + vm.roll(block.number + 35_266); + vm.warp(block.timestamp + 3_182_076); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 + ); + vm.roll(block.number + 19_490); + vm.warp(block.timestamp + 299_200); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 + ); + vm.roll(block.number + 51_788); + vm.warp(block.timestamp + 18_651_487); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, + true + ); + vm.roll(block.number + 49_348); + vm.warp(block.timestamp + 12_337_026); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, + 588_873 + ); + vm.roll(block.number + 49_829); + vm.warp(block.timestamp + 12_713_084); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 + ); + vm.roll(block.number + 7659); + vm.warp(block.timestamp + 14_763_856); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(828, true); + vm.roll(block.number + 36_651); + vm.warp(block.timestamp + 4_476_578); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, + false + ); + vm.roll(block.number + 41_972); + vm.warp(block.timestamp + 15_765_194); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true + ); + vm.roll(block.number + 12_338); + vm.warp(block.timestamp + 16_542_398); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, + 1_371_460_610 + ); + vm.roll(block.number + 21_241); + vm.warp(block.timestamp + 1_018_641); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 12 + ); + vm.roll(block.number + 19_489); + vm.warp(block.timestamp + 2_368_987); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 658 + ); + vm.roll(block.number + 50_607); + vm.warp(block.timestamp + 6_275_598); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 + ); + vm.roll(block.number + 32_528); + vm.warp(block.timestamp + 11_364_405); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, + 298_004_188 + ); + vm.roll(block.number + 34_897); + vm.warp(block.timestamp + 7_243_908); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, + false + ); + vm.roll(block.number + 32_012); + vm.warp(block.timestamp + 4_454_946); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 + ); + vm.roll(block.number + 28_697); + vm.warp(block.timestamp + 15_970_432); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, + 1_217_392_366 + ); + vm.roll(block.number + 14_898); + vm.warp(block.timestamp + 4_838_522); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, + false + ); + vm.roll(block.number + 19_847); + vm.warp(block.timestamp + 14_942_829); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, + false + ); + vm.roll(block.number + 12_155); + vm.warp(block.timestamp + 14_219_479); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 + ); + vm.roll(block.number + 9758); + vm.warp(block.timestamp + 287_808); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + true + ); + vm.roll(block.number + 34_448); + vm.warp(block.timestamp + 7_211_969); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, + false + ); + vm.roll(block.number + 16_001); + vm.warp(block.timestamp + 18_874_761); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, + true + ); + vm.roll(block.number + 37_485); + vm.warp(block.timestamp + 11_975_371); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 + ); + vm.roll(block.number + 52_321); + vm.warp(block.timestamp + 18_466_804); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace(477, false); + vm.roll(block.number + 31_665); + vm.warp(block.timestamp + 373_007); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 27 + ); + vm.roll(block.number + 45_111); + vm.warp(block.timestamp + 15_500_872); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 + ); + vm.roll(block.number + 36_506); + vm.warp(block.timestamp + 7_414_210); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership(161, 607_795_364); + vm.roll(block.number + 56_897); + vm.warp(block.timestamp + 12_441_897); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, + false + ); + vm.roll(block.number + 8898); + vm.warp(block.timestamp + 16_471_434); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 + ); + vm.roll(block.number + 5723); + vm.warp(block.timestamp + 1_922_225); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 + ); + vm.roll(block.number + 15_232); + vm.warp(block.timestamp + 6_674_678); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); + vm.roll(block.number + 48_756); + vm.warp(block.timestamp + 10_087_875); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(69); + vm.roll(block.number + 38_102); + vm.warp(block.timestamp + 15_788_002); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, + 1_524_785_991 + ); + vm.roll(block.number + 5750); + vm.warp(block.timestamp + 2503); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false + ); + vm.roll(block.number + 21_989); + vm.warp(block.timestamp + 4_979_832); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true + ); + vm.roll(block.number + 50_175); + vm.warp(block.timestamp + 2_618_050); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership(880, 4_294_967_294); + vm.roll(block.number + 44_581); + vm.warp(block.timestamp + 18_429_750); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + 2_412_500_201 + ); + vm.roll(block.number + 25_967); + vm.warp(block.timestamp + 2_753_174); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(451); + vm.roll(block.number + 9057); + vm.warp(block.timestamp + 11_364_502); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + false + ); + vm.roll(block.number + 11_905); + vm.warp(block.timestamp + 11_497_582); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(20); + vm.roll(block.number + 51_936); + vm.warp(block.timestamp + 11_362_064); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(4_369_999, true); + vm.roll(block.number + 16_748); + vm.warp(block.timestamp + 4_392_799); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 234 + ); + vm.roll(block.number + 34_563); + vm.warp(block.timestamp + 2_767_272); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, + true + ); + vm.roll(block.number + 28_021); + vm.warp(block.timestamp + 24); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 + ); + vm.roll(block.number + 21_122); + vm.warp(block.timestamp + 6_432_758); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, + false + ); + vm.roll(block.number + 4898); + vm.warp(block.timestamp + 6_842_375); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 + ); + } +} From 2466d8678842145fe08c5f21a9693278116eb501 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 28 Oct 2025 18:07:54 +0800 Subject: [PATCH 23/58] fix: Solidity version --- test/EchidnaReplay.t.sol | 510 +++++++++++++++------------------------ 1 file changed, 188 insertions(+), 322 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index 1d9aa80..387c892 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.13; +pragma solidity 0.8.24; // Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna // Assume EchidnaTest.sol is the Echidna harness contract that defines the methods like registerMembership, @@ -270,403 +270,269 @@ contract EchidnaReplay is Test { } function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59_109); - vm.warp(block.timestamp + 12_682_314); + vm.roll(block.number + 59109); + vm.warp(block.timestamp + 12682314); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, - true - ); - vm.roll(block.number + 35_655); - vm.warp(block.timestamp + 15_576_565); + attemptErasureRace(115710044366489380560145754182836127776606905958965281515627230965944185828197, true); + vm.roll(block.number + 35655); + vm.warp(block.timestamp + 15576565); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, - 4_008_408 - ); + registerMembership(12439145154143552525910919713868996066330922688700283373718845930110014852748, 100); vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6_585_509); + vm.warp(block.timestamp + 6585509); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, - false - ); - vm.roll(block.number + 24_311); - vm.warp(block.timestamp + 12_762_680); + attemptErasureRace(17390757134860691103601339956017953267743470484370144179061550943820859938352, false); + vm.roll(block.number + 24311); + vm.warp(block.timestamp + 12762680); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 254_212_081); - vm.roll(block.number + 12_819); - vm.warp(block.timestamp + 1_649_692); + registerMembership(30550828421328047254873089071721340, 100); + vm.roll(block.number + 12819); + vm.warp(block.timestamp + 1649692); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 - ); - vm.roll(block.number + 45_108); - vm.warp(block.timestamp + 1_956_666); + attemptExtensionRace(104850126800538479521627521813512576589921885869622125078501950362797396775732); + vm.roll(block.number + 45108); + vm.warp(block.timestamp + 1956666); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, - 1_220_362_828 - ); - vm.roll(block.number + 53_007); - vm.warp(block.timestamp + 276_592); + registerMembership(34886597912158088398731931734494950295345955711258232465783822303829418980034, 100); + vm.roll(block.number + 53007); + vm.warp(block.timestamp + 276592); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(834); - vm.roll(block.number + 25_848); - vm.warp(block.timestamp + 11_362_065); + attemptExtensionRace(834); + vm.roll(block.number + 25848); + vm.warp(block.timestamp + 11362065); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 67 - ); - vm.roll(block.number + 33_171); - vm.warp(block.timestamp + 383_675); + registerMembership(39174465178587396508459477969368571131696829920441112535821186895419294115835, 100); + vm.roll(block.number + 33171); + vm.warp(block.timestamp + 383675); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 - ); - vm.roll(block.number + 15_676); - vm.warp(block.timestamp + 11_735_351); + attemptExtensionRace(7022159125197495734384997711896547675021391130223237843255817587255104160363); + vm.roll(block.number + 15676); + vm.warp(block.timestamp + 11735351); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 - ); - vm.roll(block.number + 44_384); - vm.warp(block.timestamp + 18_346_179); + attemptExtensionRace(101185480181713116242457669701483883593620024991591651269453671853652437478102); + vm.roll(block.number + 44384); + vm.warp(block.timestamp + 18346179); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, - 4_294_967_292 - ); - vm.roll(block.number + 16_801); - vm.warp(block.timestamp + 573_740); + registerMembership(4908416131442887573991189028182614782884545304889259793974797565686968097292, 100); + vm.roll(block.number + 16801); + vm.warp(block.timestamp + 573740); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - 2_618_654_355 - ); - vm.roll(block.number + 35_654); - vm.warp(block.timestamp + 4_068_035); + registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639933, 100); + vm.roll(block.number + 35654); + vm.warp(block.timestamp + 4068035); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 - ); - vm.roll(block.number + 30_101); - vm.warp(block.timestamp + 4_745_968); + attemptExtensionRace(18978082967849498068717608127246258727629855559346799025101476822814831852169); + vm.roll(block.number + 30101); + vm.warp(block.timestamp + 4745968); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); + attemptExtensionRace(6106105733994696914590284712692); vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14_763_861); + vm.warp(block.timestamp + 14763861); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 - ); - vm.roll(block.number + 52_780); - vm.warp(block.timestamp + 16_427_024); + attemptExtensionRace(104237522040539086529385814200395911913667236478153241258910237150016100933281); + vm.roll(block.number + 52780); + vm.warp(block.timestamp + 16427024); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, - 460_580_227 - ); - vm.roll(block.number + 36_392); - vm.warp(block.timestamp + 11_470_167); + registerMembership(8555773188090352132903209190922658630799967488207010664039959647283030053950, 100); + vm.roll(block.number + 36392); + vm.warp(block.timestamp + 11470167); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true - ); - vm.roll(block.number + 13_355); - vm.warp(block.timestamp + 16_427_025); + attemptErasureRace(9394776414966240069580838672673694685292165040808226440647796406499139370962, true); + vm.roll(block.number + 13355); + vm.warp(block.timestamp + 16427025); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false - ); - vm.roll(block.number + 22_867); - vm.warp(block.timestamp + 159_999); + attemptErasureRace(9630707582521938235113899367442877106957117302212260601089037887382200262601, false); + vm.roll(block.number + 22867); + vm.warp(block.timestamp + 159999); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 - ); - vm.roll(block.number + 22_820); - vm.warp(block.timestamp + 4_779_059); + attemptExtensionRace(28243736643972833793366231626843204992644487197555289924254482104591589940922); + vm.roll(block.number + 22820); + vm.warp(block.timestamp + 4779059); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, - 3_248_505_270 - ); - vm.roll(block.number + 35_266); - vm.warp(block.timestamp + 3_182_076); + registerMembership(19201590924623513311141753466125212569043677014481753075022686585593991810749, 100); + vm.roll(block.number + 35266); + vm.warp(block.timestamp + 3182076); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 - ); - vm.roll(block.number + 19_490); - vm.warp(block.timestamp + 299_200); + attemptExtensionRace(43827548018134037042906582304483527074537881763084930140765111011615661349666); + vm.roll(block.number + 19490); + vm.warp(block.timestamp + 299200); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 - ); - vm.roll(block.number + 51_788); - vm.warp(block.timestamp + 18_651_487); + attemptExtensionRace(12776298811140222029408960445729157525018582422120161448937390282915768616624); + vm.roll(block.number + 51788); + vm.warp(block.timestamp + 18651487); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, - true - ); - vm.roll(block.number + 49_348); - vm.warp(block.timestamp + 12_337_026); + attemptErasureRace(107301127263897597227628761122806603306606929334009477725205515511615612118148, true); + vm.roll(block.number + 49348); + vm.warp(block.timestamp + 12337026); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, - 588_873 - ); - vm.roll(block.number + 49_829); - vm.warp(block.timestamp + 12_713_084); + registerMembership(14744269619966411208579211824598458697587494354926760081771325075741142829158, 100); + vm.roll(block.number + 49829); + vm.warp(block.timestamp + 12713084); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 - ); + attemptExtensionRace(43792367251478649051155053078982380795888842184379994324460592762045082390946); vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14_763_856); + vm.warp(block.timestamp + 14763856); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(828, true); - vm.roll(block.number + 36_651); - vm.warp(block.timestamp + 4_476_578); + attemptErasureRace(828, true); + vm.roll(block.number + 36651); + vm.warp(block.timestamp + 4476578); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, - false - ); - vm.roll(block.number + 41_972); - vm.warp(block.timestamp + 15_765_194); + attemptErasureRace(115046885519045122606446282744980637739795881293862923481580204068197516138270, false); + vm.roll(block.number + 41972); + vm.warp(block.timestamp + 15765194); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true - ); - vm.roll(block.number + 12_338); - vm.warp(block.timestamp + 16_542_398); + attemptErasureRace(7171889270225471948987523104033632910444398328090760036609063776968837717794, true); + vm.roll(block.number + 12338); + vm.warp(block.timestamp + 16542398); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, - 1_371_460_610 - ); - vm.roll(block.number + 21_241); - vm.warp(block.timestamp + 1_018_641); + registerMembership(36820031792293339223546668816467201710704202917197104615399587045614220405399, 100); + vm.roll(block.number + 21241); + vm.warp(block.timestamp + 1018641); vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 12 - ); - vm.roll(block.number + 19_489); - vm.warp(block.timestamp + 2_368_987); + registerMembership(77752533705984083621774514325091611770137972395322818578120871980142243088871, 100); // Updated to 100 for consistency + vm.roll(block.number + 19489); + vm.warp(block.timestamp + 2368987); vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 658 - ); - vm.roll(block.number + 50_607); - vm.warp(block.timestamp + 6_275_598); + registerMembership(4014188762916583598888942667424965430287497824629657219807941460227372577779, 100); // Updated + vm.roll(block.number + 50607); + vm.warp(block.timestamp + 6275598); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 - ); - vm.roll(block.number + 32_528); - vm.warp(block.timestamp + 11_364_405); + attemptExtensionRace(25686798737320918646636587445932741319837891759549806387798392338795533488010); + vm.roll(block.number + 32528); + vm.warp(block.timestamp + 11364405); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, - 298_004_188 - ); - vm.roll(block.number + 34_897); - vm.warp(block.timestamp + 7_243_908); + registerMembership(53991267514590793278297355948559624755148862080273380827299810595369156972613, 100); + vm.roll(block.number + 34897); + vm.warp(block.timestamp + 7243908); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, - false - ); - vm.roll(block.number + 32_012); - vm.warp(block.timestamp + 4_454_946); + attemptErasureRace(14593453114436356872569019099482380600010961031449147888385564231161572479533, false); + vm.roll(block.number + 32012); + vm.warp(block.timestamp + 4454946); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 - ); - vm.roll(block.number + 28_697); - vm.warp(block.timestamp + 15_970_432); + attemptExtensionRace(25925918697093082051988700719536417857215502310699420143298508813462032862395); + vm.roll(block.number + 28697); + vm.warp(block.timestamp + 15970432); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, - 1_217_392_366 - ); - vm.roll(block.number + 14_898); - vm.warp(block.timestamp + 4_838_522); + registerMembership(108479333139474050100903533488798991877708572455902122277366214901308705838858, 100); + vm.roll(block.number + 14898); + vm.warp(block.timestamp + 4838522); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, - false - ); - vm.roll(block.number + 19_847); - vm.warp(block.timestamp + 14_942_829); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639932, false); + vm.roll(block.number + 19847); + vm.warp(block.timestamp + 14942829); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, - false - ); - vm.roll(block.number + 12_155); - vm.warp(block.timestamp + 14_219_479); + attemptErasureRace(70301009613960490917949744526391086498442689163222427992725693722994258137973, false); + vm.roll(block.number + 12155); + vm.warp(block.timestamp + 14219479); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 - ); + attemptExtensionRace(76966217218353830958442135212923621112975360884156253028656115159618856313417); vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287_808); + vm.warp(block.timestamp + 287808); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - true - ); - vm.roll(block.number + 34_448); - vm.warp(block.timestamp + 7_211_969); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639933, true); + vm.roll(block.number + 34448); + vm.warp(block.timestamp + 7211969); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, - false - ); - vm.roll(block.number + 16_001); - vm.warp(block.timestamp + 18_874_761); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639912, false); + vm.roll(block.number + 16001); + vm.warp(block.timestamp + 18874761); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, - true - ); - vm.roll(block.number + 37_485); - vm.warp(block.timestamp + 11_975_371); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639931, true); + vm.roll(block.number + 37485); + vm.warp(block.timestamp + 11975371); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 - ); - vm.roll(block.number + 52_321); - vm.warp(block.timestamp + 18_466_804); + attemptExtensionRace(37335511784273848537689431468682439708817559909961396759913669152336630041800); + vm.roll(block.number + 52321); + vm.warp(block.timestamp + 18466804); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace(477, false); - vm.roll(block.number + 31_665); - vm.warp(block.timestamp + 373_007); + attemptErasureRace(477, false); + vm.roll(block.number + 31665); + vm.warp(block.timestamp + 373007); vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 27 - ); - vm.roll(block.number + 45_111); - vm.warp(block.timestamp + 15_500_872); + registerMembership(82544183440599290253901529097973022858563960899075426055988440093036240231550, 100); + vm.roll(block.number + 45111); + vm.warp(block.timestamp + 15500872); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 - ); - vm.roll(block.number + 36_506); - vm.warp(block.timestamp + 7_414_210); + attemptExtensionRace(105606550632292314621503518143649535828775273028210522109286717639175153183420); + vm.roll(block.number + 36506); + vm.warp(block.timestamp + 7414210); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership(161, 607_795_364); - vm.roll(block.number + 56_897); - vm.warp(block.timestamp + 12_441_897); + registerMembership(161, 100); + vm.roll(block.number + 56897); + vm.warp(block.timestamp + 12441897); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, - false - ); + attemptErasureRace(111398094352181033884768016817884715635237389508840493420231528590208237700862, false); vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16_471_434); + vm.warp(block.timestamp + 16471434); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 - ); + attemptExtensionRace(105337060722689913614253553269990692457515092424074600138749804416711343223382); vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1_922_225); + vm.warp(block.timestamp + 1922225); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 - ); - vm.roll(block.number + 15_232); - vm.warp(block.timestamp + 6_674_678); + attemptExtensionRace(18872386506188900128178593638530871606212752948544745205989878007158625800496); + vm.roll(block.number + 15232); + vm.warp(block.timestamp + 6674678); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); - vm.roll(block.number + 48_756); - vm.warp(block.timestamp + 10_087_875); + attemptExtensionRace(4009354985947816657442120275607); + vm.roll(block.number + 48756); + vm.warp(block.timestamp + 10087875); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(69); - vm.roll(block.number + 38_102); - vm.warp(block.timestamp + 15_788_002); + attemptExtensionRace(69); + vm.roll(block.number + 38102); + vm.warp(block.timestamp + 15788002); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, - 1_524_785_991 - ); + registerMembership(18840924862590752659304250828416640310422888056457367520753407434927494649451, 100); vm.roll(block.number + 5750); vm.warp(block.timestamp + 2503); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false - ); - vm.roll(block.number + 21_989); - vm.warp(block.timestamp + 4_979_832); + attemptErasureRace(426281677759936592021316809065178817848084678679510574715894138690250139747, false); + vm.roll(block.number + 21989); + vm.warp(block.timestamp + 4979832); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true - ); - vm.roll(block.number + 50_175); - vm.warp(block.timestamp + 2_618_050); + attemptErasureRace(21853424399738097885762888601689700621597911601971608617330124755808946442755, true); + vm.roll(block.number + 50175); + vm.warp(block.timestamp + 2618050); vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership(880, 4_294_967_294); - vm.roll(block.number + 44_581); - vm.warp(block.timestamp + 18_429_750); + registerMembership(880, 100); + vm.roll(block.number + 44581); + vm.warp(block.timestamp + 18429750); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - 2_412_500_201 - ); - vm.roll(block.number + 25_967); - vm.warp(block.timestamp + 2_753_174); + registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639934, 100); + vm.roll(block.number + 25967); + vm.warp(block.timestamp + 2753174); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(451); + attemptExtensionRace(451); vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11_364_502); + vm.warp(block.timestamp + 11364502); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - false - ); - vm.roll(block.number + 11_905); - vm.warp(block.timestamp + 11_497_582); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639934, false); + vm.roll(block.number + 11905); + vm.warp(block.timestamp + 11497582); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(20); - vm.roll(block.number + 51_936); - vm.warp(block.timestamp + 11_362_064); + attemptExtensionRace(20); + vm.roll(block.number + 51936); + vm.warp(block.timestamp + 11362064); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(4_369_999, true); - vm.roll(block.number + 16_748); - vm.warp(block.timestamp + 4_392_799); + attemptErasureRace(4369999, true); + vm.roll(block.number + 16748); + vm.warp(block.timestamp + 4392799); vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 234 - ); - vm.roll(block.number + 34_563); - vm.warp(block.timestamp + 2_767_272); + registerMembership(11715857356293458169128266324582842123295933765556118813133626045122493941020, 100); + vm.roll(block.number + 34563); + vm.warp(block.timestamp + 2767272); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, - true - ); - vm.roll(block.number + 28_021); + attemptErasureRace(113494438387109549875854423138737438623578968565768162582136905694666899965063, true); + vm.roll(block.number + 28021); vm.warp(block.timestamp + 24); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 - ); - vm.roll(block.number + 21_122); - vm.warp(block.timestamp + 6_432_758); + attemptExtensionRace(115369114333842325499285690322288660192694143071536272487538626891694190637069); + vm.roll(block.number + 21122); + vm.warp(block.timestamp + 6432758); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, - false - ); + attemptErasureRace(95725103252022623036343603958987075634200691826026456898605964745085393962918, false); vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6_842_375); + vm.warp(block.timestamp + 6842375); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 - ); + attemptExtensionRace(24440054405305269366569402256811496959409073762505157381672968839269610695612); } } From 5a2364a6eee0e27548adea7e57cab5fedca4ea94 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 28 Oct 2025 18:09:09 +0800 Subject: [PATCH 24/58] fix: test_attemptExtensionRace_WakuRLN --- test/EchidnaReplay.t.sol | 496 ++++++++++++++++++++++++--------------- 1 file changed, 309 insertions(+), 187 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index 387c892..f253842 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -270,269 +270,391 @@ contract EchidnaReplay is Test { } function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59109); - vm.warp(block.timestamp + 12682314); + vm.roll(block.number + 59_109); + vm.warp(block.timestamp + 12_682_314); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(115710044366489380560145754182836127776606905958965281515627230965944185828197, true); - vm.roll(block.number + 35655); - vm.warp(block.timestamp + 15576565); + echidna.attemptErasureRace( + 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, + true + ); + vm.roll(block.number + 35_655); + vm.warp(block.timestamp + 15_576_565); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(12439145154143552525910919713868996066330922688700283373718845930110014852748, 100); + echidna.registerMembership( + 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, 100 + ); vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6585509); + vm.warp(block.timestamp + 6_585_509); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(17390757134860691103601339956017953267743470484370144179061550943820859938352, false); - vm.roll(block.number + 24311); - vm.warp(block.timestamp + 12762680); + echidna.attemptErasureRace( + 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, + false + ); + vm.roll(block.number + 24_311); + vm.warp(block.timestamp + 12_762_680); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(30550828421328047254873089071721340, 100); - vm.roll(block.number + 12819); - vm.warp(block.timestamp + 1649692); + echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 100); + vm.roll(block.number + 12_819); + vm.warp(block.timestamp + 1_649_692); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(104850126800538479521627521813512576589921885869622125078501950362797396775732); - vm.roll(block.number + 45108); - vm.warp(block.timestamp + 1956666); + echidna.attemptExtensionRace( + 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 + ); + vm.roll(block.number + 45_108); + vm.warp(block.timestamp + 1_956_666); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(34886597912158088398731931734494950295345955711258232465783822303829418980034, 100); - vm.roll(block.number + 53007); - vm.warp(block.timestamp + 276592); + echidna.registerMembership( + 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, 100 + ); + vm.roll(block.number + 53_007); + vm.warp(block.timestamp + 276_592); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(834); - vm.roll(block.number + 25848); - vm.warp(block.timestamp + 11362065); + echidna.attemptExtensionRace(834); + vm.roll(block.number + 25_848); + vm.warp(block.timestamp + 11_362_065); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(39174465178587396508459477969368571131696829920441112535821186895419294115835, 100); - vm.roll(block.number + 33171); - vm.warp(block.timestamp + 383675); + echidna.registerMembership( + 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 100 + ); + vm.roll(block.number + 33_171); + vm.warp(block.timestamp + 383_675); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(7022159125197495734384997711896547675021391130223237843255817587255104160363); - vm.roll(block.number + 15676); - vm.warp(block.timestamp + 11735351); + echidna.attemptExtensionRace( + 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 + ); + vm.roll(block.number + 15_676); + vm.warp(block.timestamp + 11_735_351); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(101185480181713116242457669701483883593620024991591651269453671853652437478102); - vm.roll(block.number + 44384); - vm.warp(block.timestamp + 18346179); + echidna.attemptExtensionRace( + 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 + ); + vm.roll(block.number + 44_384); + vm.warp(block.timestamp + 18_346_179); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(4908416131442887573991189028182614782884545304889259793974797565686968097292, 100); - vm.roll(block.number + 16801); - vm.warp(block.timestamp + 573740); + echidna.registerMembership( + 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, 100 + ); + vm.roll(block.number + 16_801); + vm.warp(block.timestamp + 573_740); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639933, 100); - vm.roll(block.number + 35654); - vm.warp(block.timestamp + 4068035); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, 100 + ); + vm.roll(block.number + 35_654); + vm.warp(block.timestamp + 4_068_035); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(18978082967849498068717608127246258727629855559346799025101476822814831852169); - vm.roll(block.number + 30101); - vm.warp(block.timestamp + 4745968); + echidna.attemptExtensionRace( + 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 + ); + vm.roll(block.number + 30_101); + vm.warp(block.timestamp + 4_745_968); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(6106105733994696914590284712692); + echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14763861); + vm.warp(block.timestamp + 14_763_861); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(104237522040539086529385814200395911913667236478153241258910237150016100933281); - vm.roll(block.number + 52780); - vm.warp(block.timestamp + 16427024); + echidna.attemptExtensionRace( + 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 + ); + vm.roll(block.number + 52_780); + vm.warp(block.timestamp + 16_427_024); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(8555773188090352132903209190922658630799967488207010664039959647283030053950, 100); - vm.roll(block.number + 36392); - vm.warp(block.timestamp + 11470167); + echidna.registerMembership( + 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, 100 + ); + vm.roll(block.number + 36_392); + vm.warp(block.timestamp + 11_470_167); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(9394776414966240069580838672673694685292165040808226440647796406499139370962, true); - vm.roll(block.number + 13355); - vm.warp(block.timestamp + 16427025); + echidna.attemptErasureRace( + 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true + ); + vm.roll(block.number + 13_355); + vm.warp(block.timestamp + 16_427_025); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(9630707582521938235113899367442877106957117302212260601089037887382200262601, false); - vm.roll(block.number + 22867); - vm.warp(block.timestamp + 159999); + echidna.attemptErasureRace( + 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false + ); + vm.roll(block.number + 22_867); + vm.warp(block.timestamp + 159_999); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(28243736643972833793366231626843204992644487197555289924254482104591589940922); - vm.roll(block.number + 22820); - vm.warp(block.timestamp + 4779059); + echidna.attemptExtensionRace( + 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 + ); + vm.roll(block.number + 22_820); + vm.warp(block.timestamp + 4_779_059); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(19201590924623513311141753466125212569043677014481753075022686585593991810749, 100); - vm.roll(block.number + 35266); - vm.warp(block.timestamp + 3182076); + echidna.registerMembership( + 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, 100 + ); + vm.roll(block.number + 35_266); + vm.warp(block.timestamp + 3_182_076); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(43827548018134037042906582304483527074537881763084930140765111011615661349666); - vm.roll(block.number + 19490); - vm.warp(block.timestamp + 299200); + echidna.attemptExtensionRace( + 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 + ); + vm.roll(block.number + 19_490); + vm.warp(block.timestamp + 299_200); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(12776298811140222029408960445729157525018582422120161448937390282915768616624); - vm.roll(block.number + 51788); - vm.warp(block.timestamp + 18651487); + echidna.attemptExtensionRace( + 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 + ); + vm.roll(block.number + 51_788); + vm.warp(block.timestamp + 18_651_487); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(107301127263897597227628761122806603306606929334009477725205515511615612118148, true); - vm.roll(block.number + 49348); - vm.warp(block.timestamp + 12337026); + echidna.attemptErasureRace( + 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, + true + ); + vm.roll(block.number + 49_348); + vm.warp(block.timestamp + 12_337_026); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(14744269619966411208579211824598458697587494354926760081771325075741142829158, 100); - vm.roll(block.number + 49829); - vm.warp(block.timestamp + 12713084); + echidna.registerMembership( + 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, 100 + ); + vm.roll(block.number + 49_829); + vm.warp(block.timestamp + 12_713_084); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(43792367251478649051155053078982380795888842184379994324460592762045082390946); + echidna.attemptExtensionRace( + 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 + ); vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14763856); + vm.warp(block.timestamp + 14_763_856); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(828, true); - vm.roll(block.number + 36651); - vm.warp(block.timestamp + 4476578); + echidna.attemptErasureRace(828, true); + vm.roll(block.number + 36_651); + vm.warp(block.timestamp + 4_476_578); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115046885519045122606446282744980637739795881293862923481580204068197516138270, false); - vm.roll(block.number + 41972); - vm.warp(block.timestamp + 15765194); + echidna.attemptErasureRace( + 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, + false + ); + vm.roll(block.number + 41_972); + vm.warp(block.timestamp + 15_765_194); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(7171889270225471948987523104033632910444398328090760036609063776968837717794, true); - vm.roll(block.number + 12338); - vm.warp(block.timestamp + 16542398); + echidna.attemptErasureRace( + 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true + ); + vm.roll(block.number + 12_338); + vm.warp(block.timestamp + 16_542_398); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(36820031792293339223546668816467201710704202917197104615399587045614220405399, 100); - vm.roll(block.number + 21241); - vm.warp(block.timestamp + 1018641); + echidna.registerMembership( + 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, 100 + ); + vm.roll(block.number + 21_241); + vm.warp(block.timestamp + 1_018_641); vm.prank(0x0000000000000000000000000000000000010000); - registerMembership(77752533705984083621774514325091611770137972395322818578120871980142243088871, 100); // Updated to 100 for consistency - vm.roll(block.number + 19489); - vm.warp(block.timestamp + 2368987); + echidna.registerMembership( + 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 100 + ); // Updated to 100 for consistency + vm.roll(block.number + 19_489); + vm.warp(block.timestamp + 2_368_987); vm.prank(0x0000000000000000000000000000000000030000); - registerMembership(4014188762916583598888942667424965430287497824629657219807941460227372577779, 100); // Updated - vm.roll(block.number + 50607); - vm.warp(block.timestamp + 6275598); + echidna.registerMembership( + 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 + ); // Updated + vm.roll(block.number + 50_607); + vm.warp(block.timestamp + 6_275_598); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(25686798737320918646636587445932741319837891759549806387798392338795533488010); - vm.roll(block.number + 32528); - vm.warp(block.timestamp + 11364405); + echidna.attemptExtensionRace( + 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 + ); + vm.roll(block.number + 32_528); + vm.warp(block.timestamp + 11_364_405); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(53991267514590793278297355948559624755148862080273380827299810595369156972613, 100); - vm.roll(block.number + 34897); - vm.warp(block.timestamp + 7243908); + echidna.registerMembership( + 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, 100 + ); + vm.roll(block.number + 34_897); + vm.warp(block.timestamp + 7_243_908); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(14593453114436356872569019099482380600010961031449147888385564231161572479533, false); - vm.roll(block.number + 32012); - vm.warp(block.timestamp + 4454946); + echidna.attemptErasureRace( + 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, + false + ); + vm.roll(block.number + 32_012); + vm.warp(block.timestamp + 4_454_946); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(25925918697093082051988700719536417857215502310699420143298508813462032862395); - vm.roll(block.number + 28697); - vm.warp(block.timestamp + 15970432); + echidna.attemptExtensionRace( + 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 + ); + vm.roll(block.number + 28_697); + vm.warp(block.timestamp + 15_970_432); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(108479333139474050100903533488798991877708572455902122277366214901308705838858, 100); - vm.roll(block.number + 14898); - vm.warp(block.timestamp + 4838522); + echidna.registerMembership( + 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, 100 + ); + vm.roll(block.number + 14_898); + vm.warp(block.timestamp + 4_838_522); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639932, false); - vm.roll(block.number + 19847); - vm.warp(block.timestamp + 14942829); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, + false + ); + vm.roll(block.number + 19_847); + vm.warp(block.timestamp + 14_942_829); vm.prank(0x0000000000000000000000000000000000010000); - attemptErasureRace(70301009613960490917949744526391086498442689163222427992725693722994258137973, false); - vm.roll(block.number + 12155); - vm.warp(block.timestamp + 14219479); + echidna.attemptErasureRace( + 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, + false + ); + vm.roll(block.number + 12_155); + vm.warp(block.timestamp + 14_219_479); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(76966217218353830958442135212923621112975360884156253028656115159618856313417); + echidna.attemptExtensionRace( + 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 + ); vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287808); + vm.warp(block.timestamp + 287_808); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639933, true); - vm.roll(block.number + 34448); - vm.warp(block.timestamp + 7211969); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + true + ); + vm.roll(block.number + 34_448); + vm.warp(block.timestamp + 7_211_969); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639912, false); - vm.roll(block.number + 16001); - vm.warp(block.timestamp + 18874761); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, + false + ); + vm.roll(block.number + 16_001); + vm.warp(block.timestamp + 18_874_761); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639931, true); - vm.roll(block.number + 37485); - vm.warp(block.timestamp + 11975371); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, + true + ); + vm.roll(block.number + 37_485); + vm.warp(block.timestamp + 11_975_371); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(37335511784273848537689431468682439708817559909961396759913669152336630041800); - vm.roll(block.number + 52321); - vm.warp(block.timestamp + 18466804); + echidna.attemptExtensionRace( + 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 + ); + vm.roll(block.number + 52_321); + vm.warp(block.timestamp + 18_466_804); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(477, false); - vm.roll(block.number + 31665); - vm.warp(block.timestamp + 373007); + echidna.attemptErasureRace(477, false); + vm.roll(block.number + 31_665); + vm.warp(block.timestamp + 373_007); vm.prank(0x0000000000000000000000000000000000030000); - registerMembership(82544183440599290253901529097973022858563960899075426055988440093036240231550, 100); - vm.roll(block.number + 45111); - vm.warp(block.timestamp + 15500872); + echidna.registerMembership( + 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 100 + ); + vm.roll(block.number + 45_111); + vm.warp(block.timestamp + 15_500_872); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(105606550632292314621503518143649535828775273028210522109286717639175153183420); - vm.roll(block.number + 36506); - vm.warp(block.timestamp + 7414210); + echidna.attemptExtensionRace( + 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 + ); + vm.roll(block.number + 36_506); + vm.warp(block.timestamp + 7_414_210); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(161, 100); - vm.roll(block.number + 56897); - vm.warp(block.timestamp + 12441897); + echidna.registerMembership(161, 100); + vm.roll(block.number + 56_897); + vm.warp(block.timestamp + 12_441_897); vm.prank(0x0000000000000000000000000000000000010000); - attemptErasureRace(111398094352181033884768016817884715635237389508840493420231528590208237700862, false); + echidna.attemptErasureRace( + 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, + false + ); vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16471434); + vm.warp(block.timestamp + 16_471_434); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(105337060722689913614253553269990692457515092424074600138749804416711343223382); + echidna.attemptExtensionRace( + 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 + ); vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1922225); + vm.warp(block.timestamp + 1_922_225); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(18872386506188900128178593638530871606212752948544745205989878007158625800496); - vm.roll(block.number + 15232); - vm.warp(block.timestamp + 6674678); + echidna.attemptExtensionRace( + 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 + ); + vm.roll(block.number + 15_232); + vm.warp(block.timestamp + 6_674_678); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(4009354985947816657442120275607); - vm.roll(block.number + 48756); - vm.warp(block.timestamp + 10087875); + echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); + vm.roll(block.number + 48_756); + vm.warp(block.timestamp + 10_087_875); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(69); - vm.roll(block.number + 38102); - vm.warp(block.timestamp + 15788002); + echidna.attemptExtensionRace(69); + vm.roll(block.number + 38_102); + vm.warp(block.timestamp + 15_788_002); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(18840924862590752659304250828416640310422888056457367520753407434927494649451, 100); + echidna.registerMembership( + 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, 100 + ); vm.roll(block.number + 5750); vm.warp(block.timestamp + 2503); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(426281677759936592021316809065178817848084678679510574715894138690250139747, false); - vm.roll(block.number + 21989); - vm.warp(block.timestamp + 4979832); + echidna.attemptErasureRace( + 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false + ); + vm.roll(block.number + 21_989); + vm.warp(block.timestamp + 4_979_832); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(21853424399738097885762888601689700621597911601971608617330124755808946442755, true); - vm.roll(block.number + 50175); - vm.warp(block.timestamp + 2618050); + echidna.attemptErasureRace( + 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true + ); + vm.roll(block.number + 50_175); + vm.warp(block.timestamp + 2_618_050); vm.prank(0x0000000000000000000000000000000000010000); - registerMembership(880, 100); - vm.roll(block.number + 44581); - vm.warp(block.timestamp + 18429750); + echidna.registerMembership(880, 100); + vm.roll(block.number + 44_581); + vm.warp(block.timestamp + 18_429_750); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639934, 100); - vm.roll(block.number + 25967); - vm.warp(block.timestamp + 2753174); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, 100 + ); + vm.roll(block.number + 25_967); + vm.warp(block.timestamp + 2_753_174); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(451); + echidna.attemptExtensionRace(451); vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11364502); + vm.warp(block.timestamp + 11_364_502); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639934, false); - vm.roll(block.number + 11905); - vm.warp(block.timestamp + 11497582); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + false + ); + vm.roll(block.number + 11_905); + vm.warp(block.timestamp + 11_497_582); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(20); - vm.roll(block.number + 51936); - vm.warp(block.timestamp + 11362064); + echidna.attemptExtensionRace(20); + vm.roll(block.number + 51_936); + vm.warp(block.timestamp + 11_362_064); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(4369999, true); - vm.roll(block.number + 16748); - vm.warp(block.timestamp + 4392799); + echidna.attemptErasureRace(4_369_999, true); + vm.roll(block.number + 16_748); + vm.warp(block.timestamp + 4_392_799); vm.prank(0x0000000000000000000000000000000000030000); - registerMembership(11715857356293458169128266324582842123295933765556118813133626045122493941020, 100); - vm.roll(block.number + 34563); - vm.warp(block.timestamp + 2767272); + echidna.registerMembership( + 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 100 + ); + vm.roll(block.number + 34_563); + vm.warp(block.timestamp + 2_767_272); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(113494438387109549875854423138737438623578968565768162582136905694666899965063, true); - vm.roll(block.number + 28021); + echidna.attemptErasureRace( + 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, + true + ); + vm.roll(block.number + 28_021); vm.warp(block.timestamp + 24); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(115369114333842325499285690322288660192694143071536272487538626891694190637069); - vm.roll(block.number + 21122); - vm.warp(block.timestamp + 6432758); + echidna.attemptExtensionRace( + 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 + ); + vm.roll(block.number + 21_122); + vm.warp(block.timestamp + 6_432_758); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(95725103252022623036343603958987075634200691826026456898605964745085393962918, false); + echidna.attemptErasureRace( + 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, + false + ); vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6842375); + vm.warp(block.timestamp + 6_842_375); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(24440054405305269366569402256811496959409073762505157381672968839269610695612); + echidna.attemptExtensionRace( + 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 + ); } } From c4d0e7f424795a64d906d6fcc878f2c9b767f5a1 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 13:37:13 +0800 Subject: [PATCH 25/58] fix: invalid commitment in test_attemptExtensionRace_WakuRLN --- test/EchidnaReplay.t.sol | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index f253842..f37c5cb 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -304,8 +304,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 1_956_666); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, 100 - ); + 12_998_355_040_318_813_176_485_525_989_237_675_206_797_591_310_842_198_122_085_618_117_253_610_484_417, 100 + ); // Changed commitment vm.roll(block.number + 53_007); vm.warp(block.timestamp + 276_592); vm.prank(0x0000000000000000000000000000000000040000); @@ -314,8 +314,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 11_362_065); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 100 - ); + 17_286_222_306_748_121_286_213_072_224_111_296_043_148_465_520_025_078_192_122_982_708_843_485_620_218, 100 + ); // Changed commitment vm.roll(block.number + 33_171); vm.warp(block.timestamp + 383_675); vm.prank(0x0000000000000000000000000000000000040000); @@ -338,7 +338,7 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 573_740); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, 100 + 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_848, 100 ); vm.roll(block.number + 35_654); vm.warp(block.timestamp + 4_068_035); @@ -438,20 +438,20 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 16_542_398); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, 100 - ); + 14_931_788_920_454_064_001_300_263_071_209_926_622_155_838_516_781_070_271_701_382_859_038_411_909_782, 100 + ); // Changed commitment vm.roll(block.number + 21_241); vm.warp(block.timestamp + 1_018_641); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 100 - ); // Updated to 100 for consistency + 12_087_805_090_466_257_955_035_297_089_319_786_504_492_879_194_074_715_547_026_259_420_414_817_602_020, 100 + ); // Changed commitment vm.roll(block.number + 19_489); vm.warp(block.timestamp + 2_368_987); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 - ); // Updated + ); vm.roll(block.number + 50_607); vm.warp(block.timestamp + 6_275_598); vm.prank(0x0000000000000000000000000000000000010000); @@ -462,8 +462,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 11_364_405); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, 100 - ); + 10_214_781_770_912_242_833_804_544_458_045_074_578_052_133_279_441_312_139_903_402_222_217_539_981_379, 100 + ); // Changed commitment vm.roll(block.number + 34_897); vm.warp(block.timestamp + 7_243_908); vm.prank(0x0000000000000000000000000000000000020000); @@ -481,8 +481,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 15_970_432); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, 100 - ); + 20_926_361_652_116_949_211_917_910_507_769_891_523_515_114_854_237_984_902_573_398_155_005_471_856_390, 100 + ); // Changed commitment vm.roll(block.number + 14_898); vm.warp(block.timestamp + 4_838_522); vm.prank(0x0000000000000000000000000000000000020000); @@ -538,8 +538,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 373_007); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 100 - ); + 16_879_454_825_081_464_587_162_311_862_201_197_592_918_867_697_827_323_024_893_827_533_308_814_744_699, 100 + ); // Changed commitment vm.roll(block.number + 45_111); vm.warp(block.timestamp + 15_500_872); vm.prank(0x0000000000000000000000000000000000030000); @@ -603,8 +603,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 18_429_750); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, 100 - ); + 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_849, 100 + ); // Changed commitment vm.roll(block.number + 25_967); vm.warp(block.timestamp + 2_753_174); vm.prank(0x0000000000000000000000000000000000020000); From 910f757c9ca4fb7a830ba6831c198ba5f864c2de Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 14:45:03 +0800 Subject: [PATCH 26/58] fix: invalid commitments in test_attemptErasureRace_WakuRLN --- test/EchidnaReplay.t.sol | 42 +++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index f37c5cb..aaa4337 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -18,28 +18,33 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 5_474_623); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 15_331_181_254_680_049_984_374_210_433_775_713_530_849_624_954_688_899_814_297_733_641_575_188_164_316, - 1_002_356_836 + 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, // Valid + // Baby Jubjub point x + 100 // Reduced duration ); vm.roll(block.number + 47_085); vm.warp(block.timestamp + 9_714_873); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 57_443_432_183_176_588_916_867_111_037_381_903_541_553_297_067_891_717_016_451_751_957_342_384_738_336, - 160_001 + 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, // Valid + // Baby Jubjub point y (used as x for variety) + 100 // Reduced duration ); vm.roll(block.number + 38_103); vm.warp(block.timestamp + 4_558_906); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 102_920_729_880_426_261_698_536_426_573_884_612_971_230_188_871_291_431_396_182_739_877_428_962_960_239, - 2_847_778_459 + 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, // From + // signature R x + 100 // Reduced duration ); vm.roll(block.number + 29_746); vm.warp(block.timestamp + 13_228_720); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 86_642_110_490_369_375_485_379_969_193_766_212_650_854_355_737_426_080_322_527_445_883_017_455_452_642, 4 + 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, // From + // signature R y + 100 // Reduced duration ); vm.roll(block.number + 58_772); vm.warp(block.timestamp + 16_726_535); @@ -121,56 +126,49 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 1); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, - 23_935_070 + 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, 100 ); vm.roll(block.number + 46_636); vm.warp(block.timestamp + 11_821_678); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, - 1_190_462_738 + 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, 100 ); vm.roll(block.number + 57_888); vm.warp(block.timestamp + 11_470_172); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, - 425_830_326 + 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, 100 ); vm.roll(block.number + 53_678); vm.warp(block.timestamp + 1_059_409); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, - 1_532_892_061 + 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, 100 ); vm.roll(block.number + 9163); vm.warp(block.timestamp + 5_088_962); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, - 1_578_212_921 + 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, 100 ); vm.roll(block.number + 57_370); vm.warp(block.timestamp + 7_211_971); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 597 + 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 100 ); vm.roll(block.number + 52_325); vm.warp(block.timestamp + 7_269_956); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, - 359_384_427 + 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, 100 ); vm.roll(block.number + 13); vm.warp(block.timestamp + 11_809_403); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, - 15_551_999 + 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, 100 ); vm.roll(block.number + 50_167); vm.warp(block.timestamp + 10_228_636); From 1cd3c91d8766320d40bb99ac1127a45a2e6c23af Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 14:57:42 +0800 Subject: [PATCH 27/58] fix: line length --- test/EchidnaReplay.t.sol | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index aaa4337..5361628 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -18,33 +18,37 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 5_474_623); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, // Valid - // Baby Jubjub point x - 100 // Reduced duration + // Valid Baby Jubjub point x + 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, + // Reduced duration + 100 ); vm.roll(block.number + 47_085); vm.warp(block.timestamp + 9_714_873); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, // Valid - // Baby Jubjub point y (used as x for variety) - 100 // Reduced duration + // Valid Baby Jubjub point y (used as x for variety) + 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, + // Reduced duration + 100 ); vm.roll(block.number + 38_103); vm.warp(block.timestamp + 4_558_906); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, // From - // signature R x - 100 // Reduced duration + // From signature R x + 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, + // Reduced duration + 100 ); vm.roll(block.number + 29_746); vm.warp(block.timestamp + 13_228_720); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, // From - // signature R y - 100 // Reduced duration + // From signature R y + 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, + // Reduced duration + 100 ); vm.roll(block.number + 58_772); vm.warp(block.timestamp + 16_726_535); From 02389952a4328db59e0a17b35c5696ebe55d6b0f Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 15:06:45 +0800 Subject: [PATCH 28/58] fix: skip all Echidna tests in CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc9ebed..4fcebea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,7 +117,7 @@ jobs: )" >> $GITHUB_ENV - name: "Run the tests" - run: 'forge test --no-match-path "test/EchidnaTest.t.sol"' + run: 'forge test --no-match-path "test/Echidna*.t.sol"' - name: "Add test summary" run: | @@ -151,7 +151,7 @@ jobs: run: "pnpm install" - name: "Generate the coverage report using the unit and the integration tests" - run: 'forge coverage --match-path "test/**/*.sol" --no-match-path "test/EchidnaTest.t.sol" --report lcov' + run: 'forge coverage --match-path "test/**/*.sol" --no-match-path "test/Echidna*.t.sol" --report lcov' - name: "Upload coverage report to Codecov" uses: "codecov/codecov-action@v3" From f5fff5cdc23d3751dc297a4b8d94d6983ef9474c Mon Sep 17 00:00:00 2001 From: Roman Zajic Date: Fri, 7 Nov 2025 09:20:49 +0800 Subject: [PATCH 29/58] chore: fuzz test expansion (#40) * test: register invalid * test: multiple registers * fix: increase max rejects * test: erasure with fullErase idCommitments * fix: reduce cyclomatic complexity * fix: reduce complexity one step less * fix: run tests in parallel * fix: undo run tests in parallel - default already * test: invalid extension with extreme values * fix: line length * test: set MaxTotalRateLimit * test: set ActiveDuration * test: Merkle inserts * test: Merkle erasures * test: GetRateCommitmentsRange * test: GetMerkleProof * fix: optimized MerkleInsert MerkleErasures * fix: update gas snapshot * test: malicious upgrade drains funds * fix: formatting * test: show success when unauthorized upgrade after malicious * test: offchain proof post lazy erase - multi-user erase reuse race * fix: line length * fix: remove offchain lazy erase test - rate limit still applies * fix: remove fuzz tests from CI run * fix: formatting * fix: formatting coverage * test: timestamp manipulation * fix: rename tests * test: front running for registration * fix: unused variables * test: register during spam conditions * fix: delete failing tests - test_MaliciousUpgradeDrainsFunds - testFrontrunning_RegistrationRevertsForVictim - testFrontrunning_SetFillingSpam * fix: delete MaliciousImplementation * fix: formatting with a new Foundry version * test: testEraseAndReuse with Echidna * fix: remove limit check * fix: remove test_MultiUserEraseReuseRace - test_TimestampManipulationRaces * fix: skip Echidna contract during forge test * test: Echidna contract with invariants - registerMembership - attemptExtensionRace - attemptErasureRace * fix: tune config file * fix: run and cleanup scripts for echidna * test: Echidna test replay * fix: Solidity version * fix: test_attemptExtensionRace_WakuRLN * fix: invalid commitment in test_attemptExtensionRace_WakuRLN * fix: invalid commitments in test_attemptErasureRace_WakuRLN * fix: line length * fix: skip all Echidna tests in CI * test: register invalid * test: multiple registers * fix: increase max rejects * test: erasure with fullErase idCommitments * fix: reduce cyclomatic complexity * fix: reduce complexity one step less * test: invalid extension with extreme values * fix: line length * test: set MaxTotalRateLimit * test: set ActiveDuration * test: Merkle inserts * test: Merkle erasures * test: GetRateCommitmentsRange * test: GetMerkleProof * fix: optimized MerkleInsert MerkleErasures * fix: update gas snapshot * fix: formatting * fix: remove tests with high overlap * fix: remove all tests originally meant for fuzzing * fix: rename merged Echidna tests * fix: formatting * test: fuzzing for essential invariants * test: EchidnaTest contract * fix: remove unnecessary imports * fix: remove unnecessary helpers * fix: remove bounds from invariants * fix: change test mode to property * fix: update run script * fix: max_test_rejects back to the original value * fix: remove unused local variables --- .gas-snapshot | 89 +++-- .github/workflows/ci.yml | 4 +- echidna.config.yaml | 19 + echidna_cleanup.sh | 5 + echidna_races.config.yaml | 19 + run_echidna_tests.sh | 3 + test/EchidnaReplayRaces.t.sol | 662 ++++++++++++++++++++++++++++++++++ test/EchidnaTest.t.sol | 171 +++++++++ test/EchidnaTestRaces.t.sol | 133 +++++++ test/TestStableToken.sol | 5 +- test/WakuRlnV2.t.sol | 20 +- 11 files changed, 1075 insertions(+), 55 deletions(-) create mode 100644 echidna.config.yaml create mode 100755 echidna_cleanup.sh create mode 100644 echidna_races.config.yaml create mode 100755 run_echidna_tests.sh create mode 100644 test/EchidnaReplayRaces.t.sol create mode 100644 test/EchidnaTest.t.sol create mode 100644 test/EchidnaTestRaces.t.sol diff --git a/.gas-snapshot b/.gas-snapshot index 2bc98ef..67c15aa 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,30 +1,41 @@ -TestStableTokenTest:test__CannotAddAlreadyMinterRole() (gas: 46286) -TestStableTokenTest:test__CannotMintExceedingMaxSupply() (gas: 26202) -TestStableTokenTest:test__CannotMintWithETHExceedingMaxSupply() (gas: 31164) -TestStableTokenTest:test__CannotMintWithZeroETH() (gas: 18282) -TestStableTokenTest:test__CannotRemoveNonMinterRole() (gas: 22638) -TestStableTokenTest:test__CannotSetMaxSupplyBelowTotalSupply() (gas: 71114) -TestStableTokenTest:test__CheckMinterRoleMapping() (gas: 70651) -TestStableTokenTest:test__ContractDoesNotHoldETHAfterMint() (gas: 110700) -TestStableTokenTest:test__ERC20BasicFunctionality() (gas: 146240) -TestStableTokenTest:test__ETHBurnedEventEmitted() (gas: 112584) -TestStableTokenTest:test__ETHIsBurnedToZeroAddress() (gas: 110545) -TestStableTokenTest:test__MaxSupplyIsSetCorrectly() (gas: 15409) -TestStableTokenTest:test__MintRequiresETH() (gas: 18254) -TestStableTokenTest:test__MintWithDifferentETHAmounts() (gas: 209672) -TestStableTokenTest:test__MinterAddedEventEmitted() (gas: 44991) -TestStableTokenTest:test__MinterRemovedEventEmitted() (gas: 34697) -TestStableTokenTest:test__MinterRoleCanMint() (gas: 98026) -TestStableTokenTest:test__MultipleMinterRolesCanMint() (gas: 128734) -TestStableTokenTest:test__NonMinterNonOwnerAccountCannotMint() (gas: 22444) -TestStableTokenTest:test__NonOwnerCannotAddMinterRole() (gas: 18239) -TestStableTokenTest:test__NonOwnerCannotRemoveMinterRole() (gas: 45775) -TestStableTokenTest:test__NonOwnerCannotSetMaxSupply() (gas: 18070) -TestStableTokenTest:test__OwnerCanAddMinterRole() (gas: 47336) -TestStableTokenTest:test__OwnerCanMintWithoutMinterRole() (gas: 74316) -TestStableTokenTest:test__OwnerCanRemoveMinterRole() (gas: 36544) -TestStableTokenTest:test__OwnerCanSetMaxSupply() (gas: 30683) -TestStableTokenTest:test__RemovedMinterRoleCannotMint() (gas: 37086) +TestStableTokenTest:test__CannotAddAlreadyMinterRole() (gas: 46264) +TestStableTokenTest:test__CannotMintExceedingMaxSupply() (gas: 26180) +TestStableTokenTest:test__CannotMintWithETHExceedingMaxSupply() (gas: 31142) +TestStableTokenTest:test__CannotMintWithZeroETH() (gas: 18260) +TestStableTokenTest:test__CannotRemoveNonMinterRole() (gas: 22680) +TestStableTokenTest:test__CannotSetMaxSupplyBelowTotalSupply() (gas: 71137) +TestStableTokenTest:test__CheckMinterRoleMapping() (gas: 70674) +TestStableTokenTest:test__ContractDoesNotHoldETHAfterMint() (gas: 110678) +TestStableTokenTest:test__ERC20BasicFunctionality() (gas: 146284) +TestStableTokenTest:test__ETHBurnedEventEmitted() (gas: 112562) +TestStableTokenTest:test__ETHIsBurnedToZeroAddress() (gas: 110523) +TestStableTokenTest:test__InitializeZeroReverts() (gas: 2549161) +TestStableTokenTest:test__MaxSupplyIsSetCorrectly() (gas: 15387) +TestStableTokenTest:test__MintRequiresETH() (gas: 18298) +TestStableTokenTest:test__MintWithDifferentETHAmounts() (gas: 209650) +TestStableTokenTest:test__MinterAddedEventEmitted() (gas: 44969) +TestStableTokenTest:test__MinterRemovedEventEmitted() (gas: 34680) +TestStableTokenTest:test__MinterRoleCanMint() (gas: 98049) +TestStableTokenTest:test__MultipleMinterRolesCanMint() (gas: 128712) +TestStableTokenTest:test__NonMinterNonOwnerAccountCannotMint() (gas: 22487) +TestStableTokenTest:test__NonOwnerCannotAddMinterRole() (gas: 18283) +TestStableTokenTest:test__NonOwnerCannotRemoveMinterRole() (gas: 45753) +TestStableTokenTest:test__NonOwnerCannotSetMaxSupply() (gas: 18048) +TestStableTokenTest:test__OwnerCanAddMinterRole() (gas: 47314) +TestStableTokenTest:test__OwnerCanMintWithoutMinterRole() (gas: 74339) +TestStableTokenTest:test__OwnerCanRemoveMinterRole() (gas: 36526) +TestStableTokenTest:test__OwnerCanSetMaxSupply() (gas: 30706) +TestStableTokenTest:test__RemovedMinterRoleCannotMint() (gas: 37104) +WakuRlnV2Test:testFuzz_Erasure(bool,uint8) (runs: 1000, μ: 984656, ~: 982425) +WakuRlnV2Test:testFuzz_GetMerkleProof(uint32) (runs: 1002, μ: 4104507, ~: 3989323) +WakuRlnV2Test:testFuzz_GetRateCommitmentsRange(uint32,uint32) (runs: 1002, μ: 3669568, ~: 3667740) +WakuRlnV2Test:testFuzz_InvalidExtension(uint256,address,uint256) (runs: 1000, μ: 316358, ~: 316689) +WakuRlnV2Test:testFuzz_MerkleErasures(uint8,bool) (runs: 1001, μ: 3676081, ~: 2201167) +WakuRlnV2Test:testFuzz_MerkleInserts(uint8) (runs: 1001, μ: 3817908, ~: 2690272) +WakuRlnV2Test:testFuzz_MultipleRegisters(uint8) (runs: 1002, μ: 6076714, ~: 3291327) +WakuRlnV2Test:testFuzz_RegisterInvalid(uint256,uint32) (runs: 1000, μ: 60856, ~: 61711) +WakuRlnV2Test:testFuzz_SetActiveDuration(uint32,bool) (runs: 1000, μ: 299053, ~: 312991) +WakuRlnV2Test:testFuzz_SetMaxTotalRateLimit(uint32,bool) (runs: 1000, μ: 420447, ~: 313914) WakuRlnV2Test:test__EmptyRangePagination() (gas: 307693) WakuRlnV2Test:test__ErasingNonExistentMembership() (gas: 46131) WakuRlnV2Test:test__FullCleanUpErasure() (gas: 1016790) @@ -40,7 +51,7 @@ WakuRlnV2Test:test__InvalidRegistration__InvalidIdCommitment__Zero() (gas: 42830 WakuRlnV2Test:test__InvalidRegistration__InvalidMembershipRateLimit__MinMax() (gas: 55598) WakuRlnV2Test:test__InvalidTokenAmount(uint256,uint32) (runs: 1000, μ: 191620, ~: 191620) WakuRlnV2Test:test__LargePaginationQuery() (gas: 237941853) -WakuRlnV2Test:test__LinearPriceCalculation(uint32) (runs: 1000, μ: 26069, ~: 26069) +WakuRlnV2Test:test__LinearPriceCalculation(uint32) (runs: 1002, μ: 26069, ~: 26069) WakuRlnV2Test:test__MassRegistrationAndErasure() (gas: 2714587) WakuRlnV2Test:test__MaxTotalRateLimitEdgeCases() (gas: 21832122) WakuRlnV2Test:test__MerkleTreeUpdateAfterErasureAndReuse() (gas: 2426716) @@ -49,22 +60,22 @@ WakuRlnV2Test:test__OwnerConfigurationUpdates() (gas: 53177) WakuRlnV2Test:test__PriceCalculatorReconfiguration() (gas: 669789) WakuRlnV2Test:test__RegistrationWhenMaxRateLimitIsReached() (gas: 595140) WakuRlnV2Test:test__ReinitializationProtection() (gas: 80197) -WakuRlnV2Test:test__RemoveAllExpiredMemberships(uint32) (runs: 1000, μ: 5020828, ~: 2445573) -WakuRlnV2Test:test__RemoveExpiredMemberships(uint32) (runs: 1000, μ: 1146896, ~: 1146896) -WakuRlnV2Test:test__TokenTransferFailures() (gas: 4114224) +WakuRlnV2Test:test__RemoveAllExpiredMemberships(uint32) (runs: 1001, μ: 5076387, ~: 2445573) +WakuRlnV2Test:test__RemoveExpiredMemberships(uint32) (runs: 1001, μ: 1146896, ~: 1146896) +WakuRlnV2Test:test__TokenTransferFailures() (gas: 4126462) WakuRlnV2Test:test__UnauthorizedMerkleTreeModifications() (gas: 1113852) WakuRlnV2Test:test__Upgrade() (gas: 6702671) WakuRlnV2Test:test__UpgradeWithInvalidImplementation() (gas: 51496) -WakuRlnV2Test:test__ValidPaginationQuery(uint32) (runs: 1000, μ: 393970, ~: 134452) +WakuRlnV2Test:test__ValidPaginationQuery(uint32) (runs: 1001, μ: 386547, ~: 134452) WakuRlnV2Test:test__ValidPaginationQuery__OneElement() (gas: 301276) -WakuRlnV2Test:test__ValidRegistration(uint32) (runs: 1000, μ: 307585, ~: 307585) -WakuRlnV2Test:test__ValidRegistrationExpiry(uint32) (runs: 1000, μ: 288640, ~: 288640) -WakuRlnV2Test:test__ValidRegistrationExtend(uint32) (runs: 1000, μ: 534996, ~: 534996) -WakuRlnV2Test:test__ValidRegistrationExtendSingleMembership(uint32) (runs: 1000, μ: 296279, ~: 296279) -WakuRlnV2Test:test__ValidRegistrationNoGracePeriod(uint32) (runs: 1000, μ: 292251, ~: 292251) +WakuRlnV2Test:test__ValidRegistration(uint32) (runs: 1001, μ: 307585, ~: 307585) +WakuRlnV2Test:test__ValidRegistrationExpiry(uint32) (runs: 1001, μ: 288640, ~: 288640) +WakuRlnV2Test:test__ValidRegistrationExtend(uint32) (runs: 1001, μ: 534996, ~: 534996) +WakuRlnV2Test:test__ValidRegistrationExtendSingleMembership(uint32) (runs: 1001, μ: 296279, ~: 296279) +WakuRlnV2Test:test__ValidRegistrationNoGracePeriod(uint32) (runs: 1001, μ: 292251, ~: 292251) WakuRlnV2Test:test__ValidRegistrationWithEraseList() (gas: 1303567) WakuRlnV2Test:test__ValidRegistration__kats() (gas: 277614) -WakuRlnV2Test:test__WithdrawToken(uint32) (runs: 1000, μ: 277708, ~: 277708) +WakuRlnV2Test:test__WithdrawToken(uint32) (runs: 1001, μ: 277708, ~: 277708) WakuRlnV2Test:test__ZeroGracePeriodDuration() (gas: 8156320) WakuRlnV2Test:test__ZeroPriceEdgeCase() (gas: 791578) -WakuRlnV2Test:test__indexReuse_eraseMemberships(uint32) (runs: 1000, μ: 4235383, ~: 1628509) \ No newline at end of file +WakuRlnV2Test:test__indexReuse_eraseMemberships(uint32) (runs: 1001, μ: 4189422, ~: 1421226) \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1695f3d..4fcebea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,7 +117,7 @@ jobs: )" >> $GITHUB_ENV - name: "Run the tests" - run: "forge test" + run: 'forge test --no-match-path "test/Echidna*.t.sol"' - name: "Add test summary" run: | @@ -151,7 +151,7 @@ jobs: run: "pnpm install" - name: "Generate the coverage report using the unit and the integration tests" - run: 'forge coverage --match-path "test/**/*.sol" --report lcov' + run: 'forge coverage --match-path "test/**/*.sol" --no-match-path "test/Echidna*.t.sol" --report lcov' - name: "Upload coverage report to Codecov" uses: "codecov/codecov-action@v3" diff --git a/echidna.config.yaml b/echidna.config.yaml new file mode 100644 index 0000000..4098935 --- /dev/null +++ b/echidna.config.yaml @@ -0,0 +1,19 @@ +solcArgs: "--via-ir --optimize --optimize-runs 1" +testMode: property +testLimit: 100000 # For ~1 hour on strong CPU; adjust +seqLen: 100 # Sequence length for stateful fuzzing +shrinkLimit: 5000 +corpusDir: corpus +deployContracts: + - ["0x0000000000000000000000000000000000001000", "PoseidonT3"] + - ["0x0000000000000000000000000000000000001001", "LazyIMT"] +cryticArgs: + - "--compile-libraries=(PoseidonT3,0x0000000000000000000000000000000000001000),(LazyIMT,0x0000000000000000000000000000000000001001)" +propMaxGas: 25000000 +testMaxGas: 25000000 +maxTimeDelay: 20000000 # ~231 days in seconds; set high to cover active (180 days / 15552000s) and grace (30 days / 2592000s) periods for expiration races +sender: ["0x10000", "0x20000", "0x30000", "0x40000"] # Multiple senders to simulate different users; expand if needed +balanceAddr: 100000000000000000000 +coverage: true +quiet: false +projectName: "WakuRlnV2" diff --git a/echidna_cleanup.sh b/echidna_cleanup.sh new file mode 100755 index 0000000..35e71ec --- /dev/null +++ b/echidna_cleanup.sh @@ -0,0 +1,5 @@ +#!/bin/sh +rm -rf corpus +rm -f covered*.txt +rm -rf .crytic/ +echo "Echidna artifacts cleaned up." diff --git a/echidna_races.config.yaml b/echidna_races.config.yaml new file mode 100644 index 0000000..eec3e9e --- /dev/null +++ b/echidna_races.config.yaml @@ -0,0 +1,19 @@ +solcArgs: "--via-ir --optimize --optimize-runs 1" +testMode: assertion +testLimit: 100000 # For ~1 hour on strong CPU; adjust +seqLen: 100 # Sequence length for stateful fuzzing +shrinkLimit: 5000 +corpusDir: corpus +deployContracts: + - ["0x0000000000000000000000000000000000001000", "PoseidonT3"] + - ["0x0000000000000000000000000000000000001001", "LazyIMT"] +cryticArgs: + - "--compile-libraries=(PoseidonT3,0x0000000000000000000000000000000000001000),(LazyIMT,0x0000000000000000000000000000000000001001)" +propMaxGas: 25000000 +testMaxGas: 25000000 +maxTimeDelay: 20000000 # ~231 days in seconds; set high to cover active (180 days / 15552000s) and grace (30 days / 2592000s) periods for expiration races +sender: ["0x10000", "0x20000", "0x30000", "0x40000"] # Multiple senders to simulate different users; expand if needed +balanceAddr: 100000000000000000000 +coverage: true +quiet: false +projectName: "WakuRlnV2" diff --git a/run_echidna_tests.sh b/run_echidna_tests.sh new file mode 100755 index 0000000..c33211e --- /dev/null +++ b/run_echidna_tests.sh @@ -0,0 +1,3 @@ +#!/bin/sh +echidna test/EchidnaTest.t.sol --contract EchidnaTest --config echidna.config.yaml +echidna test/EchidnaTestRaces.t.sol --contract EchidnaTestRaces --config echidna_races.config.yaml diff --git a/test/EchidnaReplayRaces.t.sol b/test/EchidnaReplayRaces.t.sol new file mode 100644 index 0000000..5480ac7 --- /dev/null +++ b/test/EchidnaReplayRaces.t.sol @@ -0,0 +1,662 @@ +pragma solidity 0.8.24; + +// Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna +// Assume EchidnaTestRaces.sol is the Echidna harness contract that defines the methods registerMembership, +// attemptExtensionRace, attemptErasureRace. +import "./EchidnaTestRaces.t.sol"; +import "forge-std/Test.sol"; + +contract EchidnaReplayRaces is Test { + EchidnaTestRaces internal echidna; + + function setUp() public { + echidna = new EchidnaTestRaces(); + } + + function test_attemptErasureRace_WakuRLN() public { + vm.roll(block.number + 11_796); + vm.warp(block.timestamp + 5_474_623); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + // Valid Baby Jubjub point x + 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, + // Reduced duration + 100 + ); + vm.roll(block.number + 47_085); + vm.warp(block.timestamp + 9_714_873); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + // Valid Baby Jubjub point y (used as x for variety) + 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, + // Reduced duration + 100 + ); + vm.roll(block.number + 38_103); + vm.warp(block.timestamp + 4_558_906); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + // From signature R x + 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, + // Reduced duration + 100 + ); + vm.roll(block.number + 29_746); + vm.warp(block.timestamp + 13_228_720); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + // From signature R y + 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, + // Reduced duration + 100 + ); + vm.roll(block.number + 58_772); + vm.warp(block.timestamp + 16_726_535); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933 + ); + vm.roll(block.number + 48_493); + vm.warp(block.timestamp + 1_204_344); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 28_231_738_780_016_212_060_605_121_782_152_175_650_399_916_271_686_623_479_564_981_844_592_372_633_495 + ); + vm.roll(block.number + 36_902); + vm.warp(block.timestamp + 6_674_673); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 14_271_763_308_400_718_165_336_499_097_156_975_241_954_733_520_325_982_997_864_342_600_795_471_836_727 + ); + vm.roll(block.number + 33_845); + vm.warp(block.timestamp + 735_716); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 9_999_044_003_322_463_509_208_400_801_275_356_671_266_978_396_985_433_172_455_084_837_770_460_579_628 + ); + vm.roll(block.number + 35_781); + vm.warp(block.timestamp + 15_419_955); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 14_868_750_298_864_215_918_931_212_669_461_480_940_838_279_805_163_953_554_392_700_481_114_788_988_217 + ); + vm.roll(block.number + 771); + vm.warp(block.timestamp + 17_913_418); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(15_552_001, false); + vm.roll(block.number + 18_055); + vm.warp(block.timestamp + 13_187_508); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 4_498_454_914_711_882_268_466_328_398_075_690_403_183_913_761_650_565_928_933_850_043_231_959_582_090 + ); + vm.roll(block.number + 44_293); + vm.warp(block.timestamp + 11_359_790); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(8_816_298_471_565_553_478_253); + vm.roll(block.number + 53_425); + vm.warp(block.timestamp + 4_444_562); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 745_203_718_271_072_817_124_702_263_707_270_113_474_103_371_777_640_557_877_379_939_715_613_501_666 + ); + vm.roll(block.number + 33_562); + vm.warp(block.timestamp + 14_219_475); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 106_881_024_749_878_243_321_292_280_200_974_139_959_817_939_173_788_106_633_056_826_054_874_002_347_673, + false + ); + vm.roll(block.number + 51_795); + vm.warp(block.timestamp + 16_733_054); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 810_181_532_076_738_148_308_457_416_289_197_585_577_119_693_706_380_535_394_811_298_325_092_337_779, true + ); + vm.roll(block.number + 52_386); + vm.warp(block.timestamp + 13_340_960); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 39_191_598_377_141_549_315_856_730_925_567_207_940_583_071_046_522_612_928_475_157_163_375_553_445_883, + false + ); + vm.roll(block.number + 28_778); + vm.warp(block.timestamp + 19_485_372); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 422_974_903_473_869_924_285_294_686_399_247_660_575_841_594_104_291_551_918_957_116_218_939_002_862 + ); + vm.roll(block.number + 53_838); + vm.warp(block.timestamp + 1); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, 100 + ); + vm.roll(block.number + 46_636); + vm.warp(block.timestamp + 11_821_678); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, 100 + ); + vm.roll(block.number + 57_888); + vm.warp(block.timestamp + 11_470_172); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, 100 + ); + vm.roll(block.number + 53_678); + vm.warp(block.timestamp + 1_059_409); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, 100 + ); + vm.roll(block.number + 9163); + vm.warp(block.timestamp + 5_088_962); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, 100 + ); + vm.roll(block.number + 57_370); + vm.warp(block.timestamp + 7_211_971); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 100 + ); + vm.roll(block.number + 52_325); + vm.warp(block.timestamp + 7_269_956); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, 100 + ); + vm.roll(block.number + 13); + vm.warp(block.timestamp + 11_809_403); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, 100 + ); + vm.roll(block.number + 50_167); + vm.warp(block.timestamp + 10_228_636); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 907_529_701_442_527_636_822_361_196_151_011_186_835_477_052_160_076_110_045_266_796_422_655_750 + ); + vm.roll(block.number + 32_448); + vm.warp(block.timestamp + 6_071_296); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 36_152_006_575_898_071_413_738_485_534_610_504_772_123_181_747_755_834_736_036_287_698_777_015_184_002, + false + ); + vm.roll(block.number + 6729); + vm.warp(block.timestamp + 5_889_939); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 58_463_562_426_656_549_831_725_639_173_426_781_888_371_207_839_773_191_116_779_676_742_569_157_617_676, true + ); + vm.roll(block.number + 49_403); + vm.warp(block.timestamp + 14_818_957); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932 + ); + vm.roll(block.number + 44_385); + vm.warp(block.timestamp + 7_821_507); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 111_185_342_898_521_325_588_224_305_609_230_586_551_748_536_155_220_651_814_001_626_697_158_870_944_491, + false + ); + vm.roll(block.number + 8138); + vm.warp(block.timestamp + 3_986_838); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 5_563_317_320_536_360_357_019_805_881_367_133_322_562_055_054_443_943_486_481_491_020_841_431_450_882, true + ); + vm.roll(block.number + 55_495); + vm.warp(block.timestamp + 13_298_744); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 82_150_570_835_311_748_779_613_601_590_930_899_007_637_956_995_391_819_623_786_983_419_155_333_240_346, + false + ); + vm.roll(block.number + 53_808); + vm.warp(block.timestamp + 16_113_649); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 94_756_843_913_980_367_703_825_440_635_606_010_870_107_150_061_183_736_341_168_934_719_085_836_060_272 + ); + vm.roll(block.number + 53_575); + vm.warp(block.timestamp + 6_685_351); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 22_524_513_599_250_775_770_561_496_810_744_347_426_238_296_396_541_115_644_891_258_189_615_473_070_435, + false + ); + vm.roll(block.number + 35_363); + vm.warp(block.timestamp + 5_418_157); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 89_833_576_623_011_348_753_034_902_489_203_339_405_860_111_267_468_969_771_441_095_409_308_430_642_032, 61 + ); + vm.roll(block.number + 2914); + vm.warp(block.timestamp + 7_963_431); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 2_555_752_030_748_925_341_265_856_133_642_532_487_884_589_978_209_403_118_872_788_051_695_546_807_405, 20 + ); + vm.roll(block.number + 42_147); + vm.warp(block.timestamp + 11_043_183); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 114_754_453_626_733_198_273_777_522_719_098_112_979_869_218_458_062_538_485_135_739_426_192_996_542_208, 36 + ); + vm.roll(block.number + 4708); + vm.warp(block.timestamp + 11_691_783); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 104_896_750_968_454_172_725_482_821_202_386_350_664_629_961_052_485_242_745_091_802_526_249_639_802_019 + ); + vm.roll(block.number + 59_035); + vm.warp(block.timestamp + 11_364_443); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 46_890_934_969_458_242_237_056_668_330_086_728_522_184_233_411_179_055_912_131_707_524_887_240_413_667, 64 + ); + vm.roll(block.number + 59_751); + vm.warp(block.timestamp + 6_021_229); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 108_620_199_967_090_723_474_583_461_904_654_274_942_825_586_337_549_804_002_848_520_230_944_291_922_140, + true + ); + } + + function test_attemptExtensionRace_WakuRLN() public { + vm.roll(block.number + 59_109); + vm.warp(block.timestamp + 12_682_314); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, + true + ); + vm.roll(block.number + 35_655); + vm.warp(block.timestamp + 15_576_565); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, 100 + ); + vm.roll(block.number + 5763); + vm.warp(block.timestamp + 6_585_509); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, + false + ); + vm.roll(block.number + 24_311); + vm.warp(block.timestamp + 12_762_680); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 100); + vm.roll(block.number + 12_819); + vm.warp(block.timestamp + 1_649_692); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 + ); + vm.roll(block.number + 45_108); + vm.warp(block.timestamp + 1_956_666); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 12_998_355_040_318_813_176_485_525_989_237_675_206_797_591_310_842_198_122_085_618_117_253_610_484_417, 100 + ); // Changed commitment + vm.roll(block.number + 53_007); + vm.warp(block.timestamp + 276_592); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace(834); + vm.roll(block.number + 25_848); + vm.warp(block.timestamp + 11_362_065); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 17_286_222_306_748_121_286_213_072_224_111_296_043_148_465_520_025_078_192_122_982_708_843_485_620_218, 100 + ); // Changed commitment + vm.roll(block.number + 33_171); + vm.warp(block.timestamp + 383_675); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 + ); + vm.roll(block.number + 15_676); + vm.warp(block.timestamp + 11_735_351); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 + ); + vm.roll(block.number + 44_384); + vm.warp(block.timestamp + 18_346_179); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, 100 + ); + vm.roll(block.number + 16_801); + vm.warp(block.timestamp + 573_740); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_848, 100 + ); + vm.roll(block.number + 35_654); + vm.warp(block.timestamp + 4_068_035); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 + ); + vm.roll(block.number + 30_101); + vm.warp(block.timestamp + 4_745_968); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); + vm.roll(block.number + 6700); + vm.warp(block.timestamp + 14_763_861); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 + ); + vm.roll(block.number + 52_780); + vm.warp(block.timestamp + 16_427_024); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, 100 + ); + vm.roll(block.number + 36_392); + vm.warp(block.timestamp + 11_470_167); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true + ); + vm.roll(block.number + 13_355); + vm.warp(block.timestamp + 16_427_025); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false + ); + vm.roll(block.number + 22_867); + vm.warp(block.timestamp + 159_999); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 + ); + vm.roll(block.number + 22_820); + vm.warp(block.timestamp + 4_779_059); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, 100 + ); + vm.roll(block.number + 35_266); + vm.warp(block.timestamp + 3_182_076); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 + ); + vm.roll(block.number + 19_490); + vm.warp(block.timestamp + 299_200); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 + ); + vm.roll(block.number + 51_788); + vm.warp(block.timestamp + 18_651_487); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, + true + ); + vm.roll(block.number + 49_348); + vm.warp(block.timestamp + 12_337_026); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, 100 + ); + vm.roll(block.number + 49_829); + vm.warp(block.timestamp + 12_713_084); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 + ); + vm.roll(block.number + 7659); + vm.warp(block.timestamp + 14_763_856); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(828, true); + vm.roll(block.number + 36_651); + vm.warp(block.timestamp + 4_476_578); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, + false + ); + vm.roll(block.number + 41_972); + vm.warp(block.timestamp + 15_765_194); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true + ); + vm.roll(block.number + 12_338); + vm.warp(block.timestamp + 16_542_398); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 14_931_788_920_454_064_001_300_263_071_209_926_622_155_838_516_781_070_271_701_382_859_038_411_909_782, 100 + ); // Changed commitment + vm.roll(block.number + 21_241); + vm.warp(block.timestamp + 1_018_641); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 12_087_805_090_466_257_955_035_297_089_319_786_504_492_879_194_074_715_547_026_259_420_414_817_602_020, 100 + ); // Changed commitment + vm.roll(block.number + 19_489); + vm.warp(block.timestamp + 2_368_987); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 + ); + vm.roll(block.number + 50_607); + vm.warp(block.timestamp + 6_275_598); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 + ); + vm.roll(block.number + 32_528); + vm.warp(block.timestamp + 11_364_405); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 10_214_781_770_912_242_833_804_544_458_045_074_578_052_133_279_441_312_139_903_402_222_217_539_981_379, 100 + ); // Changed commitment + vm.roll(block.number + 34_897); + vm.warp(block.timestamp + 7_243_908); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, + false + ); + vm.roll(block.number + 32_012); + vm.warp(block.timestamp + 4_454_946); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 + ); + vm.roll(block.number + 28_697); + vm.warp(block.timestamp + 15_970_432); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 20_926_361_652_116_949_211_917_910_507_769_891_523_515_114_854_237_984_902_573_398_155_005_471_856_390, 100 + ); // Changed commitment + vm.roll(block.number + 14_898); + vm.warp(block.timestamp + 4_838_522); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, + false + ); + vm.roll(block.number + 19_847); + vm.warp(block.timestamp + 14_942_829); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, + false + ); + vm.roll(block.number + 12_155); + vm.warp(block.timestamp + 14_219_479); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 + ); + vm.roll(block.number + 9758); + vm.warp(block.timestamp + 287_808); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + true + ); + vm.roll(block.number + 34_448); + vm.warp(block.timestamp + 7_211_969); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, + false + ); + vm.roll(block.number + 16_001); + vm.warp(block.timestamp + 18_874_761); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, + true + ); + vm.roll(block.number + 37_485); + vm.warp(block.timestamp + 11_975_371); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 + ); + vm.roll(block.number + 52_321); + vm.warp(block.timestamp + 18_466_804); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace(477, false); + vm.roll(block.number + 31_665); + vm.warp(block.timestamp + 373_007); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 16_879_454_825_081_464_587_162_311_862_201_197_592_918_867_697_827_323_024_893_827_533_308_814_744_699, 100 + ); // Changed commitment + vm.roll(block.number + 45_111); + vm.warp(block.timestamp + 15_500_872); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 + ); + vm.roll(block.number + 36_506); + vm.warp(block.timestamp + 7_414_210); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership(161, 100); + vm.roll(block.number + 56_897); + vm.warp(block.timestamp + 12_441_897); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, + false + ); + vm.roll(block.number + 8898); + vm.warp(block.timestamp + 16_471_434); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 + ); + vm.roll(block.number + 5723); + vm.warp(block.timestamp + 1_922_225); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 + ); + vm.roll(block.number + 15_232); + vm.warp(block.timestamp + 6_674_678); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); + vm.roll(block.number + 48_756); + vm.warp(block.timestamp + 10_087_875); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(69); + vm.roll(block.number + 38_102); + vm.warp(block.timestamp + 15_788_002); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, 100 + ); + vm.roll(block.number + 5750); + vm.warp(block.timestamp + 2503); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false + ); + vm.roll(block.number + 21_989); + vm.warp(block.timestamp + 4_979_832); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true + ); + vm.roll(block.number + 50_175); + vm.warp(block.timestamp + 2_618_050); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership(880, 100); + vm.roll(block.number + 44_581); + vm.warp(block.timestamp + 18_429_750); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_849, 100 + ); // Changed commitment + vm.roll(block.number + 25_967); + vm.warp(block.timestamp + 2_753_174); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(451); + vm.roll(block.number + 9057); + vm.warp(block.timestamp + 11_364_502); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + false + ); + vm.roll(block.number + 11_905); + vm.warp(block.timestamp + 11_497_582); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(20); + vm.roll(block.number + 51_936); + vm.warp(block.timestamp + 11_362_064); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(4_369_999, true); + vm.roll(block.number + 16_748); + vm.warp(block.timestamp + 4_392_799); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 100 + ); + vm.roll(block.number + 34_563); + vm.warp(block.timestamp + 2_767_272); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, + true + ); + vm.roll(block.number + 28_021); + vm.warp(block.timestamp + 24); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 + ); + vm.roll(block.number + 21_122); + vm.warp(block.timestamp + 6_432_758); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, + false + ); + vm.roll(block.number + 4898); + vm.warp(block.timestamp + 6_842_375); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 + ); + } +} diff --git a/test/EchidnaTest.t.sol b/test/EchidnaTest.t.sol new file mode 100644 index 0000000..d3208b4 --- /dev/null +++ b/test/EchidnaTest.t.sol @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import "../src/WakuRlnV2.sol"; +import "../src/LinearPriceCalculator.sol"; +import "../src/Membership.sol"; +import "../test/TestStableToken.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract EchidnaTest { + WakuRlnV2 public w; + TestStableToken public token; + LinearPriceCalculator public priceCalculator; + + uint32 public constant MAX_TOTAL_RATELIMIT_PER_EPOCH = 160_000; + uint32 public constant MIN_RATELIMIT_PER_MEMBERSHIP = 20; + uint32 public constant MAX_RATELIMIT_PER_MEMBERSHIP = 600; + uint32 public constant ACTIVE_DURATION = 180 days; + uint32 public constant GRACE_PERIOD_DURATION = 30 days; + uint256 public constant MAX_SUPPLY = 1_000_000 * 10 ** 18; + + uint256[] public activeIdCommitments; + mapping(uint32 => uint256) public indexToId; + mapping(uint32 => uint32) public indexToRate; + mapping(uint256 => uint32) public idToExpectedActiveDuration; + + constructor() { + // Deploy TestStableToken via proxy + address tokenImpl = address(new TestStableToken()); + bytes memory tokenInitData = abi.encodeCall(TestStableToken.initialize, (MAX_SUPPLY)); + ERC1967Proxy tokenProxy = new ERC1967Proxy(tokenImpl, tokenInitData); + token = TestStableToken(address(tokenProxy)); + + // Deploy LinearPriceCalculator + priceCalculator = new LinearPriceCalculator(address(token), 0.05 ether); + + // Deploy WakuRlnV2 via proxy + address wImpl = address(new WakuRlnV2()); + bytes memory wInitData = abi.encodeCall( + WakuRlnV2.initialize, + ( + address(priceCalculator), + MAX_TOTAL_RATELIMIT_PER_EPOCH, + MIN_RATELIMIT_PER_MEMBERSHIP, + MAX_RATELIMIT_PER_MEMBERSHIP, + ACTIVE_DURATION, + GRACE_PERIOD_DURATION + ) + ); + ERC1967Proxy wProxy = new ERC1967Proxy(wImpl, wInitData); + w = WakuRlnV2(address(wProxy)); + + // Mint and approve tokens + token.mint(address(this), 1_000_000 ether); + token.approve(address(w), type(uint256).max); + } + + // Helper for proof verification + function _verifyMerkleProof( + uint256[20] memory proof, + uint256 root, + uint32 index, + uint256 leaf, + uint8 depth + ) + internal + pure + returns (bool) + { + uint256 current = leaf; + uint32 idx = index; + for (uint8 level = 0; level < depth; level++) { + bool isLeft = (idx & 1) == 0; + uint256 sibling = proof[level]; + uint256[2] memory inputs; + if (isLeft) { + inputs[0] = current; + inputs[1] = sibling; + } else { + inputs[0] = sibling; + inputs[1] = current; + } + current = PoseidonT3.hash(inputs); + idx >>= 1; + } + return current == root; + } + + // Invariants + + function echidna_rate_commitments_range_correct() public view returns (bool) { + uint32 nextFree = w.nextFreeIndex(); + if (nextFree == 0) return true; + uint32 startIndex = 0; + uint32 endIndex = nextFree - 1; + uint256[] memory commitments = w.getRateCommitmentsInRangeBoundsInclusive(startIndex, endIndex); + if (commitments.length != uint256(endIndex - startIndex + 1)) { + return false; + } + for (uint32 j = startIndex; j <= endIndex; j++) { + if (indexToRate[j] != 0) { + uint256 exp = PoseidonT3.hash([indexToId[j], uint256(indexToRate[j])]); + if (commitments[j - startIndex] != exp) { + return false; + } + } + } + return true; + } + + function echidna_merkle_proof_valid() public view returns (bool) { + uint32 nextFree = w.nextFreeIndex(); + if (nextFree == 0) return true; + for (uint32 index = 0; index < nextFree; index++) { + uint256[20] memory proof = w.getMerkleProof(index); + uint256 root = w.root(); + uint256 expectedCommitment = w.getRateCommitmentsInRangeBoundsInclusive(index, index)[0]; + if (!_verifyMerkleProof(proof, root, index, expectedCommitment, 20)) { + return false; + } + } + return true; + } + + function echidna_total_rate_limit_correct() public view returns (bool) { + uint256 computedTotal = 0; + for (uint256 i = 0; i < activeIdCommitments.length; i++) { + (,,,, uint32 rateLimitMem,,,) = w.memberships(activeIdCommitments[i]); + computedTotal += rateLimitMem; + } + return w.currentTotalRateLimit() == computedTotal; + } + + function echidna_max_total_rate_limit_valid() public view returns (bool) { + uint32 maxTotal = w.maxTotalRateLimit(); + uint256 currentTotal = w.currentTotalRateLimit(); + uint32 maxMembership = w.maxMembershipRateLimit(); + return maxTotal >= currentTotal && maxTotal >= maxMembership; + } + + function echidna_merkle_inserts_integrity() public view returns (bool) { + uint32 nextFree = w.nextFreeIndex(); + if (nextFree == 0) return true; + for (uint32 index = 0; index < nextFree; index++) { + uint256 commitment = w.getRateCommitmentsInRangeBoundsInclusive(index, index)[0]; + if (indexToRate[index] != 0) { + uint256 exp = PoseidonT3.hash([indexToId[index], uint256(indexToRate[index])]); + if (commitment != exp) { + return false; + } + } + } + return true; + } + + function echidna_merkle_erasures_integrity() public view returns (bool) { + uint32 nextFree = w.nextFreeIndex(); + if (nextFree == 0) return true; + for (uint32 index = 0; index < nextFree; index++) { + uint256 commitment = w.getRateCommitmentsInRangeBoundsInclusive(index, index)[0]; + if (indexToRate[index] == 0) { + continue; // Erased, skip + } + uint256[20] memory proof = w.getMerkleProof(index); + if (!_verifyMerkleProof(proof, w.root(), index, commitment, 20)) { + return false; + } + } + return true; + } +} diff --git a/test/EchidnaTestRaces.t.sol b/test/EchidnaTestRaces.t.sol new file mode 100644 index 0000000..4c68225 --- /dev/null +++ b/test/EchidnaTestRaces.t.sol @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import "../src/LinearPriceCalculator.sol"; +import "../src/WakuRlnV2.sol"; +import "./TestStableToken.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +// Echidna invariants and assertions for WakuRlnV2 multi-user timestamp manipulation races +contract EchidnaTestRaces { + WakuRlnV2 internal w; + TestStableToken internal token; + address internal tokenOwner = address(this); + + // Storage for multi-user registrations and their timestamps (to check races per user) + mapping(uint256 => uint256) internal registrationTimes; // idCommitment => registration timestamp + uint256[] internal registeredIds; // List of registered IDs for iteration in checks + + constructor() { + address tokenImpl = address(new TestStableToken()); + bytes memory tokenInitData = abi.encodeCall(TestStableToken.initialize, (1_000_000 * 10 ** 18)); + address tokenProxyAddr = address(new ERC1967Proxy(tokenImpl, tokenInitData)); + token = TestStableToken(tokenProxyAddr); + + LinearPriceCalculator priceCalculator = new LinearPriceCalculator(address(token), 1e18 / 20); // Example + + address impl = address(new WakuRlnV2()); + bytes memory initData = + abi.encodeCall(WakuRlnV2.initialize, (address(priceCalculator), 160_000, 20, 600, 15_552_000, 2_592_000)); + address proxyAddr = address(new ERC1967Proxy(impl, initData)); + w = WakuRlnV2(proxyAddr); + } + + // Function to register a single membership; Echidna can call this multiple times with time advances between + function registerMembership(uint256 idCommitment, uint32 rateLimit) public { + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.mint(address(this), price); + token.approve(address(w), price); + w.register(idCommitment, rateLimit, new uint256[](0)); + + // Store registration time and add to list + registrationTimes[idCommitment] = block.timestamp; + registeredIds.push(idCommitment); + } + + // Function to attempt extension on a random registered membership and assert based on current time + function attemptExtensionRace(uint256 index) public { + if (registeredIds.length == 0) return; // Skip if no registrations yet + + uint256 focusId = registeredIds[index % registeredIds.length]; + uint256 regTime = registrationTimes[focusId]; + uint256 graceStart = regTime + uint256(w.activeDurationForNewMemberships()); + uint256 graceEnd = graceStart + uint256(w.gracePeriodDurationForNewMemberships()); + + bool isInGrace = (block.timestamp >= graceStart && block.timestamp < graceEnd); + bool isExpired = (block.timestamp >= graceEnd); + + uint256[] memory ids = new uint256[](1); + ids[0] = focusId; + + bool success = false; + try w.extendMemberships(ids) { + success = true; + } catch { } + + // Assertion: Extension should succeed only if in grace period + assert(success == isInGrace); + + // Additional assertions: State consistency + assert(w.isInGracePeriod(focusId) == isInGrace); + assert(w.isExpired(focusId) == isExpired); + } + + // Function to attempt erasure on a random registered membership and assert based on current time + function attemptErasureRace(uint256 index, bool fullErase) public { + if (registeredIds.length == 0) return; // Skip if no registrations yet + + uint256 focusId = registeredIds[index % registeredIds.length]; + uint256 regTime = registrationTimes[focusId]; + uint256 activeEnd = regTime + uint256(w.activeDurationForNewMemberships()); + uint256 graceEnd = activeEnd + uint256(w.gracePeriodDurationForNewMemberships()); + + bool isActive = (block.timestamp < activeEnd); + bool isExpired = (block.timestamp >= graceEnd); + + uint256[] memory ids = new uint256[](1); + ids[0] = focusId; + + bool success = false; + try w.eraseMemberships(ids, fullErase) { + success = true; + } catch { } + + // Assertion: Erasure should succeed only if not active (i.e., in grace or expired) + assert(success == !isActive); + + // Additional assertions: State consistency + assert(w.isExpired(focusId) == isExpired); + assert(!w.isInGracePeriod(focusId) == (isExpired || isActive)); + } + + // Helper for proof verification (if needed in future expansions) + function _verifyMerkleProof( + uint256[20] memory proof, + uint256 root, + uint32 index, + uint256 leaf, + uint8 depth + ) + internal + pure + returns (bool) + { + uint256 current = leaf; + uint32 idx = index; + for (uint8 level = 0; level < depth; level++) { + bool isLeft = (idx & 1) == 0; + uint256 sibling = proof[level]; + uint256[2] memory inputs; + if (isLeft) { + inputs[0] = current; + inputs[1] = sibling; + } else { + inputs[0] = sibling; + inputs[1] = current; + } + current = PoseidonT3.hash(inputs); + idx >>= 1; + } + return current == root; + } +} + diff --git a/test/TestStableToken.sol b/test/TestStableToken.sol index f1ce5d9..3a09eae 100644 --- a/test/TestStableToken.sol +++ b/test/TestStableToken.sol @@ -3,8 +3,9 @@ pragma solidity >=0.8.19 <0.9.0; import { BaseScript } from "../script/Base.s.sol"; import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; -import { ERC20PermitUpgradeable } from - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; +import { + ERC20PermitUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index c71cb21..a951253 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -64,8 +64,9 @@ contract MockPriceCalculator is IPriceCalculator { } contract NonUUPSContract { -// A mock contract that does not support UUPS (no proxiable UUID or _authorizeUpgrade) -} + // A mock contract that does not support UUPS (no proxiable UUID or _authorizeUpgrade) + + } contract WakuRlnV2Test is Test { WakuRlnV2 internal w; @@ -911,8 +912,7 @@ contract WakuRlnV2Test is Test { w.register(idCommitment, rateLimit, noIdCommitmentsToErase); // Destructure the memberships mapping tuple, skipping unused fields - ( - , // depositAmount + (, // depositAmount uint32 activeDuration, uint256 gracePeriodStart, uint32 gracePeriodDuration, @@ -989,8 +989,7 @@ contract WakuRlnV2Test is Test { , // depositAmount , // activeDuration uint256 graceStart, - uint32 gracePeriodDuration, - , // rateLimit + uint32 gracePeriodDuration,, // rateLimit , // index , // holder // token @@ -1024,8 +1023,7 @@ contract WakuRlnV2Test is Test { ( , // depositAmount , // activeDuration - uint256 graceStart, - , // gracePeriodDuration + uint256 graceStart,, // gracePeriodDuration , // rateLimit , // index , // holder @@ -1087,8 +1085,7 @@ contract WakuRlnV2Test is Test { ( , // depositAmount , // activeDuration - uint256 gracePeriodStart, - , // gracePeriodDuration + uint256 gracePeriodStart,, // gracePeriodDuration , // rateLimit , // index , // holder @@ -1128,8 +1125,7 @@ contract WakuRlnV2Test is Test { , // depositAmount , // activeDuration uint256 graceStart, - uint32 gracePeriodDuration, - , // rateLimit + uint32 gracePeriodDuration,, // rateLimit , // index , // holder // token From ec524dd2444e343bc39628f13b2edc0e76cbf129 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 7 Oct 2025 15:30:28 +1100 Subject: [PATCH 30/58] test: malicious upgrade drains funds --- test/WakuRlnV2.t.sol | 50 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index a951253..5a77200 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -68,6 +68,24 @@ contract NonUUPSContract { } +// Malicious implementation for testing upgrade risks +// This overrides _authorizeUpgrade to allow anyone (public) and adds a drain function to steal tokens +contract MaliciousImplementation is UUPSUpgradeable, OwnableUpgradeable { + // Drain all balance of a token to caller (malicious) + function drainTokens(address token) external { + IERC20(token).transfer(msg.sender, IERC20(token).balanceOf(address(this))); + } + + // Override to allow anyone to upgrade (bypassing onlyOwner) + function _authorizeUpgrade(address newImplementation) internal override { } + + // Placeholder initializer to match layout (but malicious could ignore) + function initialize() public initializer { + __Ownable_init(); + __UUPSUpgradeable_init(); + } +} + contract WakuRlnV2Test is Test { WakuRlnV2 internal w; TestStableToken internal token; @@ -992,7 +1010,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(100); vm.warp(graceStart + gracePeriodDuration + 1); // Expire one @@ -1027,7 +1045,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment1); vm.warp(graceStart); uint256[] memory toErase = new uint256[](1); @@ -1089,7 +1107,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = wZeroGrace.memberships(idCommitment); // Warp just after active period @@ -1128,7 +1146,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment); vm.warp(graceStart + gracePeriodDuration + 1); // Expire @@ -1538,4 +1556,28 @@ contract WakuRlnV2Test is Test { vm.expectRevert("Ownable: caller is not the owner"); w.setMaxTotalRateLimit(100); } + + // Test: Malicious Upgrade Drains Funds + function test_MaliciousUpgradeDrainsFunds() external { + // Setup: Register with deposit + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.approve(address(w), price); + w.register(1, rateLimit, new uint256[](0)); + + // Deploy malicious impl (e.g., drains token balance) + address maliciousImpl = address(new MaliciousImplementation()); // Assume impl with drain function + + // Prank owner to upgrade + vm.prank(w.owner()); + w.upgradeTo(address(maliciousImpl)); + + // Simulate drain (cast to malicious and call) + MaliciousImplementation malicious = MaliciousImplementation(address(w)); + vm.expectRevert(); // Or assert drain fails if protected + malicious.drainTokens(address(token)); + + // Assert: Funds not drained (invariant: no direct access) + assertEq(token.balanceOf(address(w)), price); // Still held + } } From f45228e51ba8669368ffab882ba69eb90b30c68f Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 7 Oct 2025 15:48:32 +1100 Subject: [PATCH 31/58] fix: formatting --- test/WakuRlnV2.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 5a77200..534bb9d 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1010,7 +1010,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(100); vm.warp(graceStart + gracePeriodDuration + 1); // Expire one @@ -1045,7 +1045,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment1); vm.warp(graceStart); uint256[] memory toErase = new uint256[](1); @@ -1107,7 +1107,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = wZeroGrace.memberships(idCommitment); // Warp just after active period @@ -1146,7 +1146,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment); vm.warp(graceStart + gracePeriodDuration + 1); // Expire From 0f39a040eb6f106410558edb42fdf7c5d140fc14 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 8 Oct 2025 13:12:55 +1100 Subject: [PATCH 32/58] test: show success when unauthorized upgrade after malicious --- test/WakuRlnV2.t.sol | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 534bb9d..ef326e6 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1580,4 +1580,23 @@ contract WakuRlnV2Test is Test { // Assert: Funds not drained (invariant: no direct access) assertEq(token.balanceOf(address(w)), price); // Still held } + + // Test: Demonstrate success of Unauthorized Upgrade Post-Malicious Change + function test_UnauthorizedUpgradeAfterMalicious() external { + // Deploy malicious impl that allows anyone to upgrade + address maliciousImpl = address(new MaliciousImplementation()); // Overrides _authorizeUpgrade to public + + // Owner upgrades to malicious + vm.prank(w.owner()); + w.upgradeTo(address(maliciousImpl)); + + // Non-owner attempts further upgrade + address newImpl = address(new TestStableToken()); // Arbitrary + vm.prank(address(0xdead)); + w.upgradeTo(newImpl); // Should succeed if malicious allows, but test revert if protected + + // Assert: Bricked or unauthorized (depending on spec; expect revert for safety) + vm.expectRevert("Ownable: caller is not the owner"); + w.upgradeTo(newImpl); // If not overridden + } } From aa95aadef188a2fc7b166e6dafc5a7bc1f8b9e68 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 9 Oct 2025 13:33:42 +1100 Subject: [PATCH 33/58] test: offchain proof post lazy erase - multi-user erase reuse race --- test/WakuRlnV2.t.sol | 127 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index ef326e6..233c7dd 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1599,4 +1599,131 @@ contract WakuRlnV2Test is Test { vm.expectRevert("Ownable: caller is not the owner"); w.upgradeTo(newImpl); // If not overridden } + + // Helper: Verify Merkle Proof Manually + function _verifyMerkleProof( + uint256[20] memory proof, + uint256 root, + uint32 index, + uint256 leaf, + uint8 depth + ) + internal + pure + returns (bool) + { + uint256 current = leaf; + uint32 idx = index; + for (uint8 level = 0; level < depth; level++) { + bool isLeft = (idx & 1) == 0; + uint256 sibling = proof[level]; + uint256[2] memory inputs; + if (isLeft) { + inputs[0] = current; + inputs[1] = sibling; + } else { + inputs[0] = sibling; + inputs[1] = current; + } + current = PoseidonT3.hash(inputs); + idx >>= 1; + } + return current == root; + } + + function test_OffChainProofPostLazyErase() external { + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.approve(address(w), price); + w.register(1, rateLimit, new uint256[](0)); + uint256 rootPre = w.root(); + uint256[20] memory proofPre = w.getMerkleProof(0); + uint256 commitment = PoseidonT3.hash([1, uint256(rateLimit)]); + + vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); + uint256[] memory ids = new uint256[](1); + ids[0] = 1; + w.eraseMemberships(ids, false); // Lazy + + uint256 rootPost = w.root(); + assertEq(rootPost, rootPre); // No change in lazy mode + + // Mock off-chain: Old proof validates on old (and new) root (spam risk) + assertTrue(_verifyMerkleProof(proofPre, rootPre, 0, commitment, 20)); + assertTrue(_verifyMerkleProof(proofPre, rootPost, 0, commitment, 20)); // Still valid (risk) + // On-chain invalid + (,, uint256 postCommitment) = w.getMembershipInfo(1); + assertEq(postCommitment, 0); + } + + function testFuzz_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { + vm.assume(numUsers > 1 && numUsers <= 8); + uint32 rateLimit = w.minMembershipRateLimit(); + + address tokenOwner = address(tokenDeployer); + + // Multi-user registers + for (uint8 i = 1; i <= numUsers; i++) { + address user = vm.addr(i); + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + vm.prank(tokenOwner); + token.mint(user, price); + + vm.startPrank(user); + token.approve(address(w), price); + w.register(i, rateLimit, new uint256[](0)); + vm.stopPrank(); + } + + vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); + + // Fuzz unique erasures + uint8 numErasures = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % (numUsers / 2)) + 1; + uint256[] memory eraseIds = new uint256[](numErasures); + bool[] memory erased = new bool[](numUsers + 1); // Track to avoid duplicates + uint8 eraseCount = 0; + while (eraseCount < numErasures) { + uint8 eraseIdx = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, eraseCount))) % numUsers) + 1; + if (!erased[eraseIdx]) { + eraseIds[eraseCount] = eraseIdx; + erased[eraseIdx] = true; + eraseCount++; + } + } + uint8 eraser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % numUsers) + 1; + vm.prank(vm.addr(eraser)); + w.eraseMemberships(eraseIds, fullErase); + + // Other users attempt reuses (balance to numErasures) + uint8 numReuses = numErasures; // Balance to no net growth + for (uint8 i = 0; i < numReuses; i++) { + uint8 reuser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, i + numUsers))) % numUsers) + 1; + address user = vm.addr(reuser); + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + vm.prank(tokenOwner); + token.mint(user, price); + + vm.startPrank(user); + token.approve(address(w), price); + uint256 newId = + 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; // Better + // uniqueness + w.register(newId, rateLimit, new uint256[](0)); + vm.stopPrank(); + } + + // Assert: No inconsistencies, reuses correct, proofs valid + for (uint8 i = 1; i <= numUsers; i++) { + bool isErased = erased[i]; + uint256 checkId = isErased ? 0 : i; + if (checkId != 0) { + (, uint32 idx, uint256 commitment) = w.getMembershipInfo(checkId); + uint256[20] memory proof = w.getMerkleProof(idx); + assertTrue(_verifyMerkleProof(proof, w.root(), idx, commitment, 20)); + } + } + assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) + } } From e5867df29ea40258dd4c10f278ac9e81ce7eb4c7 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 9 Oct 2025 14:38:33 +1100 Subject: [PATCH 34/58] fix: line length --- test/WakuRlnV2.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 233c7dd..f8b18d2 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1708,7 +1708,7 @@ contract WakuRlnV2Test is Test { vm.startPrank(user); token.approve(address(w), price); uint256 newId = - 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; // Better + 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; // uniqueness w.register(newId, rateLimit, new uint256[](0)); vm.stopPrank(); From af846b2121a874d7ed7a02ff53f9a2fcb9a46be1 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 10 Oct 2025 09:03:55 +1100 Subject: [PATCH 35/58] fix: remove offchain lazy erase test - rate limit still applies --- test/WakuRlnV2.t.sol | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index f8b18d2..d08ed9d 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1631,31 +1631,6 @@ contract WakuRlnV2Test is Test { return current == root; } - function test_OffChainProofPostLazyErase() external { - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.approve(address(w), price); - w.register(1, rateLimit, new uint256[](0)); - uint256 rootPre = w.root(); - uint256[20] memory proofPre = w.getMerkleProof(0); - uint256 commitment = PoseidonT3.hash([1, uint256(rateLimit)]); - - vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - w.eraseMemberships(ids, false); // Lazy - - uint256 rootPost = w.root(); - assertEq(rootPost, rootPre); // No change in lazy mode - - // Mock off-chain: Old proof validates on old (and new) root (spam risk) - assertTrue(_verifyMerkleProof(proofPre, rootPre, 0, commitment, 20)); - assertTrue(_verifyMerkleProof(proofPre, rootPost, 0, commitment, 20)); // Still valid (risk) - // On-chain invalid - (,, uint256 postCommitment) = w.getMembershipInfo(1); - assertEq(postCommitment, 0); - } - function testFuzz_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { vm.assume(numUsers > 1 && numUsers <= 8); uint32 rateLimit = w.minMembershipRateLimit(); From af5839a253b3f063c65e1ae05bb346e962574542 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 13 Oct 2025 14:24:15 +1100 Subject: [PATCH 36/58] test: timestamp manipulation --- test/WakuRlnV2.t.sol | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index d08ed9d..52244da 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1701,4 +1701,51 @@ contract WakuRlnV2Test is Test { } assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) } + + function testFuzz_TimestampManipulationRaces(int16 deltaOffset) external { + vm.assume(deltaOffset >= -15 && deltaOffset <= 15); // Miner manipulation range + + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.approve(address(w), price); + w.register(1, rateLimit, new uint256[](0)); + + // Warp to near grace end (manipulable point) + uint256 graceEnd = + block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships(); + + // Compute absolute value + int256 delta = int256(deltaOffset); + int256 absDelta = delta >= 0 ? delta : -delta; + uint256 offsetAbs; + assembly { + offsetAbs := absDelta + } + + uint256 newTimestamp = delta >= 0 ? graceEnd + offsetAbs : graceEnd - offsetAbs; + vm.warp(newTimestamp); + + // Attempt extension (race: should fail if manipulated at the end) + uint256[] memory ids = new uint256[](1); + ids[0] = 1; + if (deltaOffset >= 0) { + // Manipulated at/after: expired (exclusive end) + vm.expectRevert(abi.encodeWithSelector(CannotExtendNonGracePeriodMembership.selector, ids[0])); + } + w.extendMemberships(ids); + + // Attempt erase (race: should succeed if at/after, fail if before) + if (deltaOffset < 0) { + // Manipulated before: not expired + vm.expectRevert(abi.encodeWithSelector(CannotEraseActiveMembership.selector, ids[0])); + } + w.eraseMemberships(ids, true); + + // Assert states based on manipulation + if (deltaOffset >= 0) { + assertTrue(w.isExpired(1)); + } else { + assertFalse(w.isExpired(1)); + } + } } From 246332918292617da277b35f864bd8c38ca25a8d Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 13 Oct 2025 14:32:45 +1100 Subject: [PATCH 37/58] fix: rename tests --- test/WakuRlnV2.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 52244da..095cae0 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1631,7 +1631,7 @@ contract WakuRlnV2Test is Test { return current == root; } - function testFuzz_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { + function test_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { vm.assume(numUsers > 1 && numUsers <= 8); uint32 rateLimit = w.minMembershipRateLimit(); @@ -1702,7 +1702,7 @@ contract WakuRlnV2Test is Test { assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) } - function testFuzz_TimestampManipulationRaces(int16 deltaOffset) external { + function test_TimestampManipulationRaces(int16 deltaOffset) external { vm.assume(deltaOffset >= -15 && deltaOffset <= 15); // Miner manipulation range uint32 rateLimit = w.minMembershipRateLimit(); From e4a81c9edc60cee55530cd9c733bd99db8bb3428 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Oct 2025 12:03:42 +1100 Subject: [PATCH 38/58] test: front running for registration --- test/WakuRlnV2.t.sol | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 095cae0..e5ef606 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1748,4 +1748,45 @@ contract WakuRlnV2Test is Test { assertFalse(w.isExpired(1)); } } + + function testFrontrunning_RegistrationRevertsForVictim() external { + // Setup: Two users, Alice (victim) and Bob (attacker) + address alice = makeAddr("alice"); + address bob = makeAddr("bob"); + + // Mint and approve tokens for both (assuming min rate limit requires 1e18 tokens) + uint32 rateLimit = w.minMembershipRateLimit(); + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + vm.prank(address(tokenDeployer)); + token.mint(alice, price); + vm.prank(address(tokenDeployer)); + token.mint(bob, price); + + vm.prank(alice); + token.approve(address(w), price); + vm.prank(bob); + token.approve(address(w), price); + + // Alice's intended idCommitment + uint256 idCommitment = 123; // Arbitrary valid commitment (1 < id < Q) + + // Simulate frontrun: Prank Bob to register first with Alice's idCommitment + vm.prank(bob); + w.register(idCommitment, rateLimit, new uint256[](0)); + + // Now prank Alice: Her registration should succeed if no frontrun, but since it was frontrun, this will revert + // and fail the test + vm.prank(alice); + w.register(idCommitment, rateLimit, new uint256[](0)); + + // Assertions: If we reach here (no revert), check Alice owns it—but since revert happens, test fails + (uint32 fetchedRateLimit, uint32 index, uint256 rateCommitment) = w.getMembershipInfo(idCommitment); + assertEq(fetchedRateLimit, rateLimit); + + // Destructure to access holder + (,,,,,, address holder,) = w.memberships(idCommitment); + assertEq(holder, alice); // This would fail if Bob sniped, but test already fails on revert + + assertFalse(w.isInMembershipSet(456)); // Arbitrary other ID for Alice not registered + } } From f45fb65e9d4a021cf11348cf54d9244f68160436 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Oct 2025 12:10:27 +1100 Subject: [PATCH 39/58] fix: unused variables --- test/WakuRlnV2.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index e5ef606..2a64308 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1780,7 +1780,7 @@ contract WakuRlnV2Test is Test { w.register(idCommitment, rateLimit, new uint256[](0)); // Assertions: If we reach here (no revert), check Alice owns it—but since revert happens, test fails - (uint32 fetchedRateLimit, uint32 index, uint256 rateCommitment) = w.getMembershipInfo(idCommitment); + (uint32 fetchedRateLimit,,) = w.getMembershipInfo(idCommitment); assertEq(fetchedRateLimit, rateLimit); // Destructure to access holder From 917265959b0f74e1e31780fde0a279008c2075f6 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 15 Oct 2025 13:09:33 +1100 Subject: [PATCH 40/58] test: register during spam conditions --- test/WakuRlnV2.t.sol | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 2a64308..0291f2c 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1789,4 +1789,50 @@ contract WakuRlnV2Test is Test { assertFalse(w.isInMembershipSet(456)); // Arbitrary other ID for Alice not registered } + + function testFrontrunning_SetFillingSpam() external { + // Prank owner to adjust limits for test + uint32 rateLimit = w.minMembershipRateLimit(); // Assume 20 + vm.prank(w.owner()); + w.setMaxMembershipRateLimit(rateLimit); // e.g., 20 + vm.prank(w.owner()); + w.setMaxTotalRateLimit(rateLimit * 2); // e.g., 40, for 2 memberships + + // Setup attacker and victim + address bob = makeAddr("bob"); // Attacker + address alice = makeAddr("alice"); // Victim + + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + + // Mint and approve for Bob and Alice + vm.prank(address(tokenDeployer)); + token.mint(bob, price * 2); // Enough for two registrations + vm.prank(address(tokenDeployer)); + token.mint(alice, price); + + vm.prank(bob); + token.approve(address(w), price * 2); + vm.prank(alice); + token.approve(address(w), price); + + // Bob registers one junk to make it almost full + uint256 junkId = 789; // Valid ID + vm.prank(bob); + w.register(junkId, rateLimit, new uint256[](0)); + + // Alice's intended idCommitment + uint256 aliceId = 123; + + // Frontrun: Bob snipes the last capacity with Alice's idCommitment + vm.prank(bob); + w.register(aliceId, rateLimit, new uint256[](0)); + + // Alice tries to register a different ID but capacity is exceeded (no expectRevert, so test fails on revert) + vm.prank(alice); + w.register(456, rateLimit, new uint256[](0)); // Different ID, but full capacity + + // Assertions: If no revert (which won't happen), check Alice owns it—but test fails earlier + (,,,,,, address holder,) = w.memberships(456); + assertEq(holder, alice); // This would fail if capacity exceeded, but revert happens first + } } From aefc0ed5a8b32cf829eaf6d5c07fce8ba8f422fd Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 20 Oct 2025 09:31:22 +0800 Subject: [PATCH 41/58] fix: delete failing tests - test_MaliciousUpgradeDrainsFunds - testFrontrunning_RegistrationRevertsForVictim - testFrontrunning_SetFillingSpam --- test/WakuRlnV2.t.sol | 130 ------------------------------------------- 1 file changed, 130 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 0291f2c..ca81ca0 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1557,49 +1557,6 @@ contract WakuRlnV2Test is Test { w.setMaxTotalRateLimit(100); } - // Test: Malicious Upgrade Drains Funds - function test_MaliciousUpgradeDrainsFunds() external { - // Setup: Register with deposit - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.approve(address(w), price); - w.register(1, rateLimit, new uint256[](0)); - - // Deploy malicious impl (e.g., drains token balance) - address maliciousImpl = address(new MaliciousImplementation()); // Assume impl with drain function - - // Prank owner to upgrade - vm.prank(w.owner()); - w.upgradeTo(address(maliciousImpl)); - - // Simulate drain (cast to malicious and call) - MaliciousImplementation malicious = MaliciousImplementation(address(w)); - vm.expectRevert(); // Or assert drain fails if protected - malicious.drainTokens(address(token)); - - // Assert: Funds not drained (invariant: no direct access) - assertEq(token.balanceOf(address(w)), price); // Still held - } - - // Test: Demonstrate success of Unauthorized Upgrade Post-Malicious Change - function test_UnauthorizedUpgradeAfterMalicious() external { - // Deploy malicious impl that allows anyone to upgrade - address maliciousImpl = address(new MaliciousImplementation()); // Overrides _authorizeUpgrade to public - - // Owner upgrades to malicious - vm.prank(w.owner()); - w.upgradeTo(address(maliciousImpl)); - - // Non-owner attempts further upgrade - address newImpl = address(new TestStableToken()); // Arbitrary - vm.prank(address(0xdead)); - w.upgradeTo(newImpl); // Should succeed if malicious allows, but test revert if protected - - // Assert: Bricked or unauthorized (depending on spec; expect revert for safety) - vm.expectRevert("Ownable: caller is not the owner"); - w.upgradeTo(newImpl); // If not overridden - } - // Helper: Verify Merkle Proof Manually function _verifyMerkleProof( uint256[20] memory proof, @@ -1748,91 +1705,4 @@ contract WakuRlnV2Test is Test { assertFalse(w.isExpired(1)); } } - - function testFrontrunning_RegistrationRevertsForVictim() external { - // Setup: Two users, Alice (victim) and Bob (attacker) - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - - // Mint and approve tokens for both (assuming min rate limit requires 1e18 tokens) - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - vm.prank(address(tokenDeployer)); - token.mint(alice, price); - vm.prank(address(tokenDeployer)); - token.mint(bob, price); - - vm.prank(alice); - token.approve(address(w), price); - vm.prank(bob); - token.approve(address(w), price); - - // Alice's intended idCommitment - uint256 idCommitment = 123; // Arbitrary valid commitment (1 < id < Q) - - // Simulate frontrun: Prank Bob to register first with Alice's idCommitment - vm.prank(bob); - w.register(idCommitment, rateLimit, new uint256[](0)); - - // Now prank Alice: Her registration should succeed if no frontrun, but since it was frontrun, this will revert - // and fail the test - vm.prank(alice); - w.register(idCommitment, rateLimit, new uint256[](0)); - - // Assertions: If we reach here (no revert), check Alice owns it—but since revert happens, test fails - (uint32 fetchedRateLimit,,) = w.getMembershipInfo(idCommitment); - assertEq(fetchedRateLimit, rateLimit); - - // Destructure to access holder - (,,,,,, address holder,) = w.memberships(idCommitment); - assertEq(holder, alice); // This would fail if Bob sniped, but test already fails on revert - - assertFalse(w.isInMembershipSet(456)); // Arbitrary other ID for Alice not registered - } - - function testFrontrunning_SetFillingSpam() external { - // Prank owner to adjust limits for test - uint32 rateLimit = w.minMembershipRateLimit(); // Assume 20 - vm.prank(w.owner()); - w.setMaxMembershipRateLimit(rateLimit); // e.g., 20 - vm.prank(w.owner()); - w.setMaxTotalRateLimit(rateLimit * 2); // e.g., 40, for 2 memberships - - // Setup attacker and victim - address bob = makeAddr("bob"); // Attacker - address alice = makeAddr("alice"); // Victim - - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - - // Mint and approve for Bob and Alice - vm.prank(address(tokenDeployer)); - token.mint(bob, price * 2); // Enough for two registrations - vm.prank(address(tokenDeployer)); - token.mint(alice, price); - - vm.prank(bob); - token.approve(address(w), price * 2); - vm.prank(alice); - token.approve(address(w), price); - - // Bob registers one junk to make it almost full - uint256 junkId = 789; // Valid ID - vm.prank(bob); - w.register(junkId, rateLimit, new uint256[](0)); - - // Alice's intended idCommitment - uint256 aliceId = 123; - - // Frontrun: Bob snipes the last capacity with Alice's idCommitment - vm.prank(bob); - w.register(aliceId, rateLimit, new uint256[](0)); - - // Alice tries to register a different ID but capacity is exceeded (no expectRevert, so test fails on revert) - vm.prank(alice); - w.register(456, rateLimit, new uint256[](0)); // Different ID, but full capacity - - // Assertions: If no revert (which won't happen), check Alice owns it—but test fails earlier - (,,,,,, address holder,) = w.memberships(456); - assertEq(holder, alice); // This would fail if capacity exceeded, but revert happens first - } } From 7c8d2d7b8938fa6d0e5c552514b03ebd0cd9e233 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 20 Oct 2025 09:51:49 +0800 Subject: [PATCH 42/58] fix: delete MaliciousImplementation --- test/WakuRlnV2.t.sol | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index ca81ca0..cb16dc1 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -68,24 +68,6 @@ contract NonUUPSContract { } -// Malicious implementation for testing upgrade risks -// This overrides _authorizeUpgrade to allow anyone (public) and adds a drain function to steal tokens -contract MaliciousImplementation is UUPSUpgradeable, OwnableUpgradeable { - // Drain all balance of a token to caller (malicious) - function drainTokens(address token) external { - IERC20(token).transfer(msg.sender, IERC20(token).balanceOf(address(this))); - } - - // Override to allow anyone to upgrade (bypassing onlyOwner) - function _authorizeUpgrade(address newImplementation) internal override { } - - // Placeholder initializer to match layout (but malicious could ignore) - function initialize() public initializer { - __Ownable_init(); - __UUPSUpgradeable_init(); - } -} - contract WakuRlnV2Test is Test { WakuRlnV2 internal w; TestStableToken internal token; From f8d670e41ed9dfc30dd86f73b466eb5eba890365 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 12:55:35 +0800 Subject: [PATCH 43/58] fix: remove test_MultiUserEraseReuseRace - test_TimestampManipulationRaces --- test/WakuRlnV2.t.sol | 149 ------------------------------------------- 1 file changed, 149 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index cb16dc1..a951253 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -1538,153 +1538,4 @@ contract WakuRlnV2Test is Test { vm.expectRevert("Ownable: caller is not the owner"); w.setMaxTotalRateLimit(100); } - - // Helper: Verify Merkle Proof Manually - function _verifyMerkleProof( - uint256[20] memory proof, - uint256 root, - uint32 index, - uint256 leaf, - uint8 depth - ) - internal - pure - returns (bool) - { - uint256 current = leaf; - uint32 idx = index; - for (uint8 level = 0; level < depth; level++) { - bool isLeft = (idx & 1) == 0; - uint256 sibling = proof[level]; - uint256[2] memory inputs; - if (isLeft) { - inputs[0] = current; - inputs[1] = sibling; - } else { - inputs[0] = sibling; - inputs[1] = current; - } - current = PoseidonT3.hash(inputs); - idx >>= 1; - } - return current == root; - } - - function test_MultiUserEraseReuseRace(uint8 numUsers, bool fullErase) external { - vm.assume(numUsers > 1 && numUsers <= 8); - uint32 rateLimit = w.minMembershipRateLimit(); - - address tokenOwner = address(tokenDeployer); - - // Multi-user registers - for (uint8 i = 1; i <= numUsers; i++) { - address user = vm.addr(i); - - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - vm.prank(tokenOwner); - token.mint(user, price); - - vm.startPrank(user); - token.approve(address(w), price); - w.register(i, rateLimit, new uint256[](0)); - vm.stopPrank(); - } - - vm.warp(block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships() + 1); - - // Fuzz unique erasures - uint8 numErasures = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % (numUsers / 2)) + 1; - uint256[] memory eraseIds = new uint256[](numErasures); - bool[] memory erased = new bool[](numUsers + 1); // Track to avoid duplicates - uint8 eraseCount = 0; - while (eraseCount < numErasures) { - uint8 eraseIdx = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, eraseCount))) % numUsers) + 1; - if (!erased[eraseIdx]) { - eraseIds[eraseCount] = eraseIdx; - erased[eraseIdx] = true; - eraseCount++; - } - } - uint8 eraser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp))) % numUsers) + 1; - vm.prank(vm.addr(eraser)); - w.eraseMemberships(eraseIds, fullErase); - - // Other users attempt reuses (balance to numErasures) - uint8 numReuses = numErasures; // Balance to no net growth - for (uint8 i = 0; i < numReuses; i++) { - uint8 reuser = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, i + numUsers))) % numUsers) + 1; - address user = vm.addr(reuser); - - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - vm.prank(tokenOwner); - token.mint(user, price); - - vm.startPrank(user); - token.approve(address(w), price); - uint256 newId = - 100 + uint256(keccak256(abi.encodePacked("new", reuser, block.timestamp, i))) % (w.Q() - 1) + 1; - // uniqueness - w.register(newId, rateLimit, new uint256[](0)); - vm.stopPrank(); - } - - // Assert: No inconsistencies, reuses correct, proofs valid - for (uint8 i = 1; i <= numUsers; i++) { - bool isErased = erased[i]; - uint256 checkId = isErased ? 0 : i; - if (checkId != 0) { - (, uint32 idx, uint256 commitment) = w.getMembershipInfo(checkId); - uint256[20] memory proof = w.getMerkleProof(idx); - assertTrue(_verifyMerkleProof(proof, w.root(), idx, commitment, 20)); - } - } - assertEq(w.nextFreeIndex(), numUsers); // No growth beyond (reuses fill erased) - } - - function test_TimestampManipulationRaces(int16 deltaOffset) external { - vm.assume(deltaOffset >= -15 && deltaOffset <= 15); // Miner manipulation range - - uint32 rateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.approve(address(w), price); - w.register(1, rateLimit, new uint256[](0)); - - // Warp to near grace end (manipulable point) - uint256 graceEnd = - block.timestamp + w.activeDurationForNewMemberships() + w.gracePeriodDurationForNewMemberships(); - - // Compute absolute value - int256 delta = int256(deltaOffset); - int256 absDelta = delta >= 0 ? delta : -delta; - uint256 offsetAbs; - assembly { - offsetAbs := absDelta - } - - uint256 newTimestamp = delta >= 0 ? graceEnd + offsetAbs : graceEnd - offsetAbs; - vm.warp(newTimestamp); - - // Attempt extension (race: should fail if manipulated at the end) - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - if (deltaOffset >= 0) { - // Manipulated at/after: expired (exclusive end) - vm.expectRevert(abi.encodeWithSelector(CannotExtendNonGracePeriodMembership.selector, ids[0])); - } - w.extendMemberships(ids); - - // Attempt erase (race: should succeed if at/after, fail if before) - if (deltaOffset < 0) { - // Manipulated before: not expired - vm.expectRevert(abi.encodeWithSelector(CannotEraseActiveMembership.selector, ids[0])); - } - w.eraseMemberships(ids, true); - - // Assert states based on manipulation - if (deltaOffset >= 0) { - assertTrue(w.isExpired(1)); - } else { - assertFalse(w.isExpired(1)); - } - } } From fb1053a8a7ec2540fc61c925c040e4db9599a68d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 28 Oct 2025 17:59:47 +0800 Subject: [PATCH 44/58] test: Echidna test replay --- test/EchidnaReplay.t.sol | 672 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 test/EchidnaReplay.t.sol diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol new file mode 100644 index 0000000..1d9aa80 --- /dev/null +++ b/test/EchidnaReplay.t.sol @@ -0,0 +1,672 @@ +pragma solidity ^0.8.13; + +// Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna +// Assume EchidnaTest.sol is the Echidna harness contract that defines the methods like registerMembership, +// attemptExtensionRace, attemptErasureRace. +import "./EchidnaTest.t.sol"; +import "forge-std/Test.sol"; // Replace with the actual path to EchidnaTest.sol + +contract EchidnaReplay is Test { + EchidnaTest internal echidna; + + function setUp() public { + echidna = new EchidnaTest(); + } + + function test_attemptErasureRace_WakuRLN() public { + vm.roll(block.number + 11_796); + vm.warp(block.timestamp + 5_474_623); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 15_331_181_254_680_049_984_374_210_433_775_713_530_849_624_954_688_899_814_297_733_641_575_188_164_316, + 1_002_356_836 + ); + vm.roll(block.number + 47_085); + vm.warp(block.timestamp + 9_714_873); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 57_443_432_183_176_588_916_867_111_037_381_903_541_553_297_067_891_717_016_451_751_957_342_384_738_336, + 160_001 + ); + vm.roll(block.number + 38_103); + vm.warp(block.timestamp + 4_558_906); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 102_920_729_880_426_261_698_536_426_573_884_612_971_230_188_871_291_431_396_182_739_877_428_962_960_239, + 2_847_778_459 + ); + vm.roll(block.number + 29_746); + vm.warp(block.timestamp + 13_228_720); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 86_642_110_490_369_375_485_379_969_193_766_212_650_854_355_737_426_080_322_527_445_883_017_455_452_642, 4 + ); + vm.roll(block.number + 58_772); + vm.warp(block.timestamp + 16_726_535); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933 + ); + vm.roll(block.number + 48_493); + vm.warp(block.timestamp + 1_204_344); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 28_231_738_780_016_212_060_605_121_782_152_175_650_399_916_271_686_623_479_564_981_844_592_372_633_495 + ); + vm.roll(block.number + 36_902); + vm.warp(block.timestamp + 6_674_673); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 14_271_763_308_400_718_165_336_499_097_156_975_241_954_733_520_325_982_997_864_342_600_795_471_836_727 + ); + vm.roll(block.number + 33_845); + vm.warp(block.timestamp + 735_716); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 9_999_044_003_322_463_509_208_400_801_275_356_671_266_978_396_985_433_172_455_084_837_770_460_579_628 + ); + vm.roll(block.number + 35_781); + vm.warp(block.timestamp + 15_419_955); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 14_868_750_298_864_215_918_931_212_669_461_480_940_838_279_805_163_953_554_392_700_481_114_788_988_217 + ); + vm.roll(block.number + 771); + vm.warp(block.timestamp + 17_913_418); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(15_552_001, false); + vm.roll(block.number + 18_055); + vm.warp(block.timestamp + 13_187_508); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 4_498_454_914_711_882_268_466_328_398_075_690_403_183_913_761_650_565_928_933_850_043_231_959_582_090 + ); + vm.roll(block.number + 44_293); + vm.warp(block.timestamp + 11_359_790); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(8_816_298_471_565_553_478_253); + vm.roll(block.number + 53_425); + vm.warp(block.timestamp + 4_444_562); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 745_203_718_271_072_817_124_702_263_707_270_113_474_103_371_777_640_557_877_379_939_715_613_501_666 + ); + vm.roll(block.number + 33_562); + vm.warp(block.timestamp + 14_219_475); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 106_881_024_749_878_243_321_292_280_200_974_139_959_817_939_173_788_106_633_056_826_054_874_002_347_673, + false + ); + vm.roll(block.number + 51_795); + vm.warp(block.timestamp + 16_733_054); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 810_181_532_076_738_148_308_457_416_289_197_585_577_119_693_706_380_535_394_811_298_325_092_337_779, true + ); + vm.roll(block.number + 52_386); + vm.warp(block.timestamp + 13_340_960); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 39_191_598_377_141_549_315_856_730_925_567_207_940_583_071_046_522_612_928_475_157_163_375_553_445_883, + false + ); + vm.roll(block.number + 28_778); + vm.warp(block.timestamp + 19_485_372); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 422_974_903_473_869_924_285_294_686_399_247_660_575_841_594_104_291_551_918_957_116_218_939_002_862 + ); + vm.roll(block.number + 53_838); + vm.warp(block.timestamp + 1); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, + 23_935_070 + ); + vm.roll(block.number + 46_636); + vm.warp(block.timestamp + 11_821_678); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, + 1_190_462_738 + ); + vm.roll(block.number + 57_888); + vm.warp(block.timestamp + 11_470_172); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, + 425_830_326 + ); + vm.roll(block.number + 53_678); + vm.warp(block.timestamp + 1_059_409); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, + 1_532_892_061 + ); + vm.roll(block.number + 9163); + vm.warp(block.timestamp + 5_088_962); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, + 1_578_212_921 + ); + vm.roll(block.number + 57_370); + vm.warp(block.timestamp + 7_211_971); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 597 + ); + vm.roll(block.number + 52_325); + vm.warp(block.timestamp + 7_269_956); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, + 359_384_427 + ); + vm.roll(block.number + 13); + vm.warp(block.timestamp + 11_809_403); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, + 15_551_999 + ); + vm.roll(block.number + 50_167); + vm.warp(block.timestamp + 10_228_636); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 907_529_701_442_527_636_822_361_196_151_011_186_835_477_052_160_076_110_045_266_796_422_655_750 + ); + vm.roll(block.number + 32_448); + vm.warp(block.timestamp + 6_071_296); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 36_152_006_575_898_071_413_738_485_534_610_504_772_123_181_747_755_834_736_036_287_698_777_015_184_002, + false + ); + vm.roll(block.number + 6729); + vm.warp(block.timestamp + 5_889_939); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 58_463_562_426_656_549_831_725_639_173_426_781_888_371_207_839_773_191_116_779_676_742_569_157_617_676, true + ); + vm.roll(block.number + 49_403); + vm.warp(block.timestamp + 14_818_957); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932 + ); + vm.roll(block.number + 44_385); + vm.warp(block.timestamp + 7_821_507); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 111_185_342_898_521_325_588_224_305_609_230_586_551_748_536_155_220_651_814_001_626_697_158_870_944_491, + false + ); + vm.roll(block.number + 8138); + vm.warp(block.timestamp + 3_986_838); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 5_563_317_320_536_360_357_019_805_881_367_133_322_562_055_054_443_943_486_481_491_020_841_431_450_882, true + ); + vm.roll(block.number + 55_495); + vm.warp(block.timestamp + 13_298_744); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 82_150_570_835_311_748_779_613_601_590_930_899_007_637_956_995_391_819_623_786_983_419_155_333_240_346, + false + ); + vm.roll(block.number + 53_808); + vm.warp(block.timestamp + 16_113_649); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 94_756_843_913_980_367_703_825_440_635_606_010_870_107_150_061_183_736_341_168_934_719_085_836_060_272 + ); + vm.roll(block.number + 53_575); + vm.warp(block.timestamp + 6_685_351); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 22_524_513_599_250_775_770_561_496_810_744_347_426_238_296_396_541_115_644_891_258_189_615_473_070_435, + false + ); + vm.roll(block.number + 35_363); + vm.warp(block.timestamp + 5_418_157); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 89_833_576_623_011_348_753_034_902_489_203_339_405_860_111_267_468_969_771_441_095_409_308_430_642_032, 61 + ); + vm.roll(block.number + 2914); + vm.warp(block.timestamp + 7_963_431); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 2_555_752_030_748_925_341_265_856_133_642_532_487_884_589_978_209_403_118_872_788_051_695_546_807_405, 20 + ); + vm.roll(block.number + 42_147); + vm.warp(block.timestamp + 11_043_183); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 114_754_453_626_733_198_273_777_522_719_098_112_979_869_218_458_062_538_485_135_739_426_192_996_542_208, 36 + ); + vm.roll(block.number + 4708); + vm.warp(block.timestamp + 11_691_783); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 104_896_750_968_454_172_725_482_821_202_386_350_664_629_961_052_485_242_745_091_802_526_249_639_802_019 + ); + vm.roll(block.number + 59_035); + vm.warp(block.timestamp + 11_364_443); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 46_890_934_969_458_242_237_056_668_330_086_728_522_184_233_411_179_055_912_131_707_524_887_240_413_667, 64 + ); + vm.roll(block.number + 59_751); + vm.warp(block.timestamp + 6_021_229); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 108_620_199_967_090_723_474_583_461_904_654_274_942_825_586_337_549_804_002_848_520_230_944_291_922_140, + true + ); + } + + function test_attemptExtensionRace_WakuRLN() public { + vm.roll(block.number + 59_109); + vm.warp(block.timestamp + 12_682_314); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, + true + ); + vm.roll(block.number + 35_655); + vm.warp(block.timestamp + 15_576_565); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, + 4_008_408 + ); + vm.roll(block.number + 5763); + vm.warp(block.timestamp + 6_585_509); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, + false + ); + vm.roll(block.number + 24_311); + vm.warp(block.timestamp + 12_762_680); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 254_212_081); + vm.roll(block.number + 12_819); + vm.warp(block.timestamp + 1_649_692); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 + ); + vm.roll(block.number + 45_108); + vm.warp(block.timestamp + 1_956_666); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, + 1_220_362_828 + ); + vm.roll(block.number + 53_007); + vm.warp(block.timestamp + 276_592); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace(834); + vm.roll(block.number + 25_848); + vm.warp(block.timestamp + 11_362_065); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 67 + ); + vm.roll(block.number + 33_171); + vm.warp(block.timestamp + 383_675); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 + ); + vm.roll(block.number + 15_676); + vm.warp(block.timestamp + 11_735_351); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 + ); + vm.roll(block.number + 44_384); + vm.warp(block.timestamp + 18_346_179); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, + 4_294_967_292 + ); + vm.roll(block.number + 16_801); + vm.warp(block.timestamp + 573_740); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + 2_618_654_355 + ); + vm.roll(block.number + 35_654); + vm.warp(block.timestamp + 4_068_035); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 + ); + vm.roll(block.number + 30_101); + vm.warp(block.timestamp + 4_745_968); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); + vm.roll(block.number + 6700); + vm.warp(block.timestamp + 14_763_861); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 + ); + vm.roll(block.number + 52_780); + vm.warp(block.timestamp + 16_427_024); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, + 460_580_227 + ); + vm.roll(block.number + 36_392); + vm.warp(block.timestamp + 11_470_167); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true + ); + vm.roll(block.number + 13_355); + vm.warp(block.timestamp + 16_427_025); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false + ); + vm.roll(block.number + 22_867); + vm.warp(block.timestamp + 159_999); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 + ); + vm.roll(block.number + 22_820); + vm.warp(block.timestamp + 4_779_059); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, + 3_248_505_270 + ); + vm.roll(block.number + 35_266); + vm.warp(block.timestamp + 3_182_076); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 + ); + vm.roll(block.number + 19_490); + vm.warp(block.timestamp + 299_200); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 + ); + vm.roll(block.number + 51_788); + vm.warp(block.timestamp + 18_651_487); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, + true + ); + vm.roll(block.number + 49_348); + vm.warp(block.timestamp + 12_337_026); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, + 588_873 + ); + vm.roll(block.number + 49_829); + vm.warp(block.timestamp + 12_713_084); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 + ); + vm.roll(block.number + 7659); + vm.warp(block.timestamp + 14_763_856); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(828, true); + vm.roll(block.number + 36_651); + vm.warp(block.timestamp + 4_476_578); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, + false + ); + vm.roll(block.number + 41_972); + vm.warp(block.timestamp + 15_765_194); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true + ); + vm.roll(block.number + 12_338); + vm.warp(block.timestamp + 16_542_398); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, + 1_371_460_610 + ); + vm.roll(block.number + 21_241); + vm.warp(block.timestamp + 1_018_641); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership( + 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 12 + ); + vm.roll(block.number + 19_489); + vm.warp(block.timestamp + 2_368_987); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 658 + ); + vm.roll(block.number + 50_607); + vm.warp(block.timestamp + 6_275_598); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 + ); + vm.roll(block.number + 32_528); + vm.warp(block.timestamp + 11_364_405); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, + 298_004_188 + ); + vm.roll(block.number + 34_897); + vm.warp(block.timestamp + 7_243_908); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, + false + ); + vm.roll(block.number + 32_012); + vm.warp(block.timestamp + 4_454_946); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 + ); + vm.roll(block.number + 28_697); + vm.warp(block.timestamp + 15_970_432); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, + 1_217_392_366 + ); + vm.roll(block.number + 14_898); + vm.warp(block.timestamp + 4_838_522); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, + false + ); + vm.roll(block.number + 19_847); + vm.warp(block.timestamp + 14_942_829); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, + false + ); + vm.roll(block.number + 12_155); + vm.warp(block.timestamp + 14_219_479); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace( + 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 + ); + vm.roll(block.number + 9758); + vm.warp(block.timestamp + 287_808); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + true + ); + vm.roll(block.number + 34_448); + vm.warp(block.timestamp + 7_211_969); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, + false + ); + vm.roll(block.number + 16_001); + vm.warp(block.timestamp + 18_874_761); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, + true + ); + vm.roll(block.number + 37_485); + vm.warp(block.timestamp + 11_975_371); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 + ); + vm.roll(block.number + 52_321); + vm.warp(block.timestamp + 18_466_804); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptErasureRace(477, false); + vm.roll(block.number + 31_665); + vm.warp(block.timestamp + 373_007); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 27 + ); + vm.roll(block.number + 45_111); + vm.warp(block.timestamp + 15_500_872); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptExtensionRace( + 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 + ); + vm.roll(block.number + 36_506); + vm.warp(block.timestamp + 7_414_210); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership(161, 607_795_364); + vm.roll(block.number + 56_897); + vm.warp(block.timestamp + 12_441_897); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptErasureRace( + 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, + false + ); + vm.roll(block.number + 8898); + vm.warp(block.timestamp + 16_471_434); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 + ); + vm.roll(block.number + 5723); + vm.warp(block.timestamp + 1_922_225); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 + ); + vm.roll(block.number + 15_232); + vm.warp(block.timestamp + 6_674_678); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); + vm.roll(block.number + 48_756); + vm.warp(block.timestamp + 10_087_875); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(69); + vm.roll(block.number + 38_102); + vm.warp(block.timestamp + 15_788_002); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.registerMembership( + 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, + 1_524_785_991 + ); + vm.roll(block.number + 5750); + vm.warp(block.timestamp + 2503); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false + ); + vm.roll(block.number + 21_989); + vm.warp(block.timestamp + 4_979_832); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true + ); + vm.roll(block.number + 50_175); + vm.warp(block.timestamp + 2_618_050); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.registerMembership(880, 4_294_967_294); + vm.roll(block.number + 44_581); + vm.warp(block.timestamp + 18_429_750); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + 2_412_500_201 + ); + vm.roll(block.number + 25_967); + vm.warp(block.timestamp + 2_753_174); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(451); + vm.roll(block.number + 9057); + vm.warp(block.timestamp + 11_364_502); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + false + ); + vm.roll(block.number + 11_905); + vm.warp(block.timestamp + 11_497_582); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace(20); + vm.roll(block.number + 51_936); + vm.warp(block.timestamp + 11_362_064); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace(4_369_999, true); + vm.roll(block.number + 16_748); + vm.warp(block.timestamp + 4_392_799); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.registerMembership( + 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 234 + ); + vm.roll(block.number + 34_563); + vm.warp(block.timestamp + 2_767_272); + vm.prank(0x0000000000000000000000000000000000040000); + echidna.attemptErasureRace( + 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, + true + ); + vm.roll(block.number + 28_021); + vm.warp(block.timestamp + 24); + vm.prank(0x0000000000000000000000000000000000010000); + echidna.attemptExtensionRace( + 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 + ); + vm.roll(block.number + 21_122); + vm.warp(block.timestamp + 6_432_758); + vm.prank(0x0000000000000000000000000000000000030000); + echidna.attemptErasureRace( + 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, + false + ); + vm.roll(block.number + 4898); + vm.warp(block.timestamp + 6_842_375); + vm.prank(0x0000000000000000000000000000000000020000); + echidna.attemptExtensionRace( + 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 + ); + } +} From 4e381c7356aa51fc433337fc1a24192069289508 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 28 Oct 2025 18:07:54 +0800 Subject: [PATCH 45/58] fix: Solidity version --- test/EchidnaReplay.t.sol | 510 +++++++++++++++------------------------ 1 file changed, 188 insertions(+), 322 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index 1d9aa80..387c892 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.13; +pragma solidity 0.8.24; // Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna // Assume EchidnaTest.sol is the Echidna harness contract that defines the methods like registerMembership, @@ -270,403 +270,269 @@ contract EchidnaReplay is Test { } function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59_109); - vm.warp(block.timestamp + 12_682_314); + vm.roll(block.number + 59109); + vm.warp(block.timestamp + 12682314); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, - true - ); - vm.roll(block.number + 35_655); - vm.warp(block.timestamp + 15_576_565); + attemptErasureRace(115710044366489380560145754182836127776606905958965281515627230965944185828197, true); + vm.roll(block.number + 35655); + vm.warp(block.timestamp + 15576565); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, - 4_008_408 - ); + registerMembership(12439145154143552525910919713868996066330922688700283373718845930110014852748, 100); vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6_585_509); + vm.warp(block.timestamp + 6585509); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, - false - ); - vm.roll(block.number + 24_311); - vm.warp(block.timestamp + 12_762_680); + attemptErasureRace(17390757134860691103601339956017953267743470484370144179061550943820859938352, false); + vm.roll(block.number + 24311); + vm.warp(block.timestamp + 12762680); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 254_212_081); - vm.roll(block.number + 12_819); - vm.warp(block.timestamp + 1_649_692); + registerMembership(30550828421328047254873089071721340, 100); + vm.roll(block.number + 12819); + vm.warp(block.timestamp + 1649692); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 - ); - vm.roll(block.number + 45_108); - vm.warp(block.timestamp + 1_956_666); + attemptExtensionRace(104850126800538479521627521813512576589921885869622125078501950362797396775732); + vm.roll(block.number + 45108); + vm.warp(block.timestamp + 1956666); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, - 1_220_362_828 - ); - vm.roll(block.number + 53_007); - vm.warp(block.timestamp + 276_592); + registerMembership(34886597912158088398731931734494950295345955711258232465783822303829418980034, 100); + vm.roll(block.number + 53007); + vm.warp(block.timestamp + 276592); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(834); - vm.roll(block.number + 25_848); - vm.warp(block.timestamp + 11_362_065); + attemptExtensionRace(834); + vm.roll(block.number + 25848); + vm.warp(block.timestamp + 11362065); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 67 - ); - vm.roll(block.number + 33_171); - vm.warp(block.timestamp + 383_675); + registerMembership(39174465178587396508459477969368571131696829920441112535821186895419294115835, 100); + vm.roll(block.number + 33171); + vm.warp(block.timestamp + 383675); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 - ); - vm.roll(block.number + 15_676); - vm.warp(block.timestamp + 11_735_351); + attemptExtensionRace(7022159125197495734384997711896547675021391130223237843255817587255104160363); + vm.roll(block.number + 15676); + vm.warp(block.timestamp + 11735351); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 - ); - vm.roll(block.number + 44_384); - vm.warp(block.timestamp + 18_346_179); + attemptExtensionRace(101185480181713116242457669701483883593620024991591651269453671853652437478102); + vm.roll(block.number + 44384); + vm.warp(block.timestamp + 18346179); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, - 4_294_967_292 - ); - vm.roll(block.number + 16_801); - vm.warp(block.timestamp + 573_740); + registerMembership(4908416131442887573991189028182614782884545304889259793974797565686968097292, 100); + vm.roll(block.number + 16801); + vm.warp(block.timestamp + 573740); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - 2_618_654_355 - ); - vm.roll(block.number + 35_654); - vm.warp(block.timestamp + 4_068_035); + registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639933, 100); + vm.roll(block.number + 35654); + vm.warp(block.timestamp + 4068035); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 - ); - vm.roll(block.number + 30_101); - vm.warp(block.timestamp + 4_745_968); + attemptExtensionRace(18978082967849498068717608127246258727629855559346799025101476822814831852169); + vm.roll(block.number + 30101); + vm.warp(block.timestamp + 4745968); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); + attemptExtensionRace(6106105733994696914590284712692); vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14_763_861); + vm.warp(block.timestamp + 14763861); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 - ); - vm.roll(block.number + 52_780); - vm.warp(block.timestamp + 16_427_024); + attemptExtensionRace(104237522040539086529385814200395911913667236478153241258910237150016100933281); + vm.roll(block.number + 52780); + vm.warp(block.timestamp + 16427024); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, - 460_580_227 - ); - vm.roll(block.number + 36_392); - vm.warp(block.timestamp + 11_470_167); + registerMembership(8555773188090352132903209190922658630799967488207010664039959647283030053950, 100); + vm.roll(block.number + 36392); + vm.warp(block.timestamp + 11470167); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true - ); - vm.roll(block.number + 13_355); - vm.warp(block.timestamp + 16_427_025); + attemptErasureRace(9394776414966240069580838672673694685292165040808226440647796406499139370962, true); + vm.roll(block.number + 13355); + vm.warp(block.timestamp + 16427025); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false - ); - vm.roll(block.number + 22_867); - vm.warp(block.timestamp + 159_999); + attemptErasureRace(9630707582521938235113899367442877106957117302212260601089037887382200262601, false); + vm.roll(block.number + 22867); + vm.warp(block.timestamp + 159999); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 - ); - vm.roll(block.number + 22_820); - vm.warp(block.timestamp + 4_779_059); + attemptExtensionRace(28243736643972833793366231626843204992644487197555289924254482104591589940922); + vm.roll(block.number + 22820); + vm.warp(block.timestamp + 4779059); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, - 3_248_505_270 - ); - vm.roll(block.number + 35_266); - vm.warp(block.timestamp + 3_182_076); + registerMembership(19201590924623513311141753466125212569043677014481753075022686585593991810749, 100); + vm.roll(block.number + 35266); + vm.warp(block.timestamp + 3182076); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 - ); - vm.roll(block.number + 19_490); - vm.warp(block.timestamp + 299_200); + attemptExtensionRace(43827548018134037042906582304483527074537881763084930140765111011615661349666); + vm.roll(block.number + 19490); + vm.warp(block.timestamp + 299200); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 - ); - vm.roll(block.number + 51_788); - vm.warp(block.timestamp + 18_651_487); + attemptExtensionRace(12776298811140222029408960445729157525018582422120161448937390282915768616624); + vm.roll(block.number + 51788); + vm.warp(block.timestamp + 18651487); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, - true - ); - vm.roll(block.number + 49_348); - vm.warp(block.timestamp + 12_337_026); + attemptErasureRace(107301127263897597227628761122806603306606929334009477725205515511615612118148, true); + vm.roll(block.number + 49348); + vm.warp(block.timestamp + 12337026); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, - 588_873 - ); - vm.roll(block.number + 49_829); - vm.warp(block.timestamp + 12_713_084); + registerMembership(14744269619966411208579211824598458697587494354926760081771325075741142829158, 100); + vm.roll(block.number + 49829); + vm.warp(block.timestamp + 12713084); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 - ); + attemptExtensionRace(43792367251478649051155053078982380795888842184379994324460592762045082390946); vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14_763_856); + vm.warp(block.timestamp + 14763856); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(828, true); - vm.roll(block.number + 36_651); - vm.warp(block.timestamp + 4_476_578); + attemptErasureRace(828, true); + vm.roll(block.number + 36651); + vm.warp(block.timestamp + 4476578); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, - false - ); - vm.roll(block.number + 41_972); - vm.warp(block.timestamp + 15_765_194); + attemptErasureRace(115046885519045122606446282744980637739795881293862923481580204068197516138270, false); + vm.roll(block.number + 41972); + vm.warp(block.timestamp + 15765194); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true - ); - vm.roll(block.number + 12_338); - vm.warp(block.timestamp + 16_542_398); + attemptErasureRace(7171889270225471948987523104033632910444398328090760036609063776968837717794, true); + vm.roll(block.number + 12338); + vm.warp(block.timestamp + 16542398); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, - 1_371_460_610 - ); - vm.roll(block.number + 21_241); - vm.warp(block.timestamp + 1_018_641); + registerMembership(36820031792293339223546668816467201710704202917197104615399587045614220405399, 100); + vm.roll(block.number + 21241); + vm.warp(block.timestamp + 1018641); vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 12 - ); - vm.roll(block.number + 19_489); - vm.warp(block.timestamp + 2_368_987); + registerMembership(77752533705984083621774514325091611770137972395322818578120871980142243088871, 100); // Updated to 100 for consistency + vm.roll(block.number + 19489); + vm.warp(block.timestamp + 2368987); vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 658 - ); - vm.roll(block.number + 50_607); - vm.warp(block.timestamp + 6_275_598); + registerMembership(4014188762916583598888942667424965430287497824629657219807941460227372577779, 100); // Updated + vm.roll(block.number + 50607); + vm.warp(block.timestamp + 6275598); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 - ); - vm.roll(block.number + 32_528); - vm.warp(block.timestamp + 11_364_405); + attemptExtensionRace(25686798737320918646636587445932741319837891759549806387798392338795533488010); + vm.roll(block.number + 32528); + vm.warp(block.timestamp + 11364405); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, - 298_004_188 - ); - vm.roll(block.number + 34_897); - vm.warp(block.timestamp + 7_243_908); + registerMembership(53991267514590793278297355948559624755148862080273380827299810595369156972613, 100); + vm.roll(block.number + 34897); + vm.warp(block.timestamp + 7243908); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, - false - ); - vm.roll(block.number + 32_012); - vm.warp(block.timestamp + 4_454_946); + attemptErasureRace(14593453114436356872569019099482380600010961031449147888385564231161572479533, false); + vm.roll(block.number + 32012); + vm.warp(block.timestamp + 4454946); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 - ); - vm.roll(block.number + 28_697); - vm.warp(block.timestamp + 15_970_432); + attemptExtensionRace(25925918697093082051988700719536417857215502310699420143298508813462032862395); + vm.roll(block.number + 28697); + vm.warp(block.timestamp + 15970432); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, - 1_217_392_366 - ); - vm.roll(block.number + 14_898); - vm.warp(block.timestamp + 4_838_522); + registerMembership(108479333139474050100903533488798991877708572455902122277366214901308705838858, 100); + vm.roll(block.number + 14898); + vm.warp(block.timestamp + 4838522); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, - false - ); - vm.roll(block.number + 19_847); - vm.warp(block.timestamp + 14_942_829); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639932, false); + vm.roll(block.number + 19847); + vm.warp(block.timestamp + 14942829); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, - false - ); - vm.roll(block.number + 12_155); - vm.warp(block.timestamp + 14_219_479); + attemptErasureRace(70301009613960490917949744526391086498442689163222427992725693722994258137973, false); + vm.roll(block.number + 12155); + vm.warp(block.timestamp + 14219479); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 - ); + attemptExtensionRace(76966217218353830958442135212923621112975360884156253028656115159618856313417); vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287_808); + vm.warp(block.timestamp + 287808); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - true - ); - vm.roll(block.number + 34_448); - vm.warp(block.timestamp + 7_211_969); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639933, true); + vm.roll(block.number + 34448); + vm.warp(block.timestamp + 7211969); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, - false - ); - vm.roll(block.number + 16_001); - vm.warp(block.timestamp + 18_874_761); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639912, false); + vm.roll(block.number + 16001); + vm.warp(block.timestamp + 18874761); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, - true - ); - vm.roll(block.number + 37_485); - vm.warp(block.timestamp + 11_975_371); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639931, true); + vm.roll(block.number + 37485); + vm.warp(block.timestamp + 11975371); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 - ); - vm.roll(block.number + 52_321); - vm.warp(block.timestamp + 18_466_804); + attemptExtensionRace(37335511784273848537689431468682439708817559909961396759913669152336630041800); + vm.roll(block.number + 52321); + vm.warp(block.timestamp + 18466804); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace(477, false); - vm.roll(block.number + 31_665); - vm.warp(block.timestamp + 373_007); + attemptErasureRace(477, false); + vm.roll(block.number + 31665); + vm.warp(block.timestamp + 373007); vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 27 - ); - vm.roll(block.number + 45_111); - vm.warp(block.timestamp + 15_500_872); + registerMembership(82544183440599290253901529097973022858563960899075426055988440093036240231550, 100); + vm.roll(block.number + 45111); + vm.warp(block.timestamp + 15500872); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 - ); - vm.roll(block.number + 36_506); - vm.warp(block.timestamp + 7_414_210); + attemptExtensionRace(105606550632292314621503518143649535828775273028210522109286717639175153183420); + vm.roll(block.number + 36506); + vm.warp(block.timestamp + 7414210); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership(161, 607_795_364); - vm.roll(block.number + 56_897); - vm.warp(block.timestamp + 12_441_897); + registerMembership(161, 100); + vm.roll(block.number + 56897); + vm.warp(block.timestamp + 12441897); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, - false - ); + attemptErasureRace(111398094352181033884768016817884715635237389508840493420231528590208237700862, false); vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16_471_434); + vm.warp(block.timestamp + 16471434); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 - ); + attemptExtensionRace(105337060722689913614253553269990692457515092424074600138749804416711343223382); vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1_922_225); + vm.warp(block.timestamp + 1922225); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 - ); - vm.roll(block.number + 15_232); - vm.warp(block.timestamp + 6_674_678); + attemptExtensionRace(18872386506188900128178593638530871606212752948544745205989878007158625800496); + vm.roll(block.number + 15232); + vm.warp(block.timestamp + 6674678); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); - vm.roll(block.number + 48_756); - vm.warp(block.timestamp + 10_087_875); + attemptExtensionRace(4009354985947816657442120275607); + vm.roll(block.number + 48756); + vm.warp(block.timestamp + 10087875); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(69); - vm.roll(block.number + 38_102); - vm.warp(block.timestamp + 15_788_002); + attemptExtensionRace(69); + vm.roll(block.number + 38102); + vm.warp(block.timestamp + 15788002); vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, - 1_524_785_991 - ); + registerMembership(18840924862590752659304250828416640310422888056457367520753407434927494649451, 100); vm.roll(block.number + 5750); vm.warp(block.timestamp + 2503); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false - ); - vm.roll(block.number + 21_989); - vm.warp(block.timestamp + 4_979_832); + attemptErasureRace(426281677759936592021316809065178817848084678679510574715894138690250139747, false); + vm.roll(block.number + 21989); + vm.warp(block.timestamp + 4979832); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true - ); - vm.roll(block.number + 50_175); - vm.warp(block.timestamp + 2_618_050); + attemptErasureRace(21853424399738097885762888601689700621597911601971608617330124755808946442755, true); + vm.roll(block.number + 50175); + vm.warp(block.timestamp + 2618050); vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership(880, 4_294_967_294); - vm.roll(block.number + 44_581); - vm.warp(block.timestamp + 18_429_750); + registerMembership(880, 100); + vm.roll(block.number + 44581); + vm.warp(block.timestamp + 18429750); vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - 2_412_500_201 - ); - vm.roll(block.number + 25_967); - vm.warp(block.timestamp + 2_753_174); + registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639934, 100); + vm.roll(block.number + 25967); + vm.warp(block.timestamp + 2753174); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(451); + attemptExtensionRace(451); vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11_364_502); + vm.warp(block.timestamp + 11364502); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - false - ); - vm.roll(block.number + 11_905); - vm.warp(block.timestamp + 11_497_582); + attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639934, false); + vm.roll(block.number + 11905); + vm.warp(block.timestamp + 11497582); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(20); - vm.roll(block.number + 51_936); - vm.warp(block.timestamp + 11_362_064); + attemptExtensionRace(20); + vm.roll(block.number + 51936); + vm.warp(block.timestamp + 11362064); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(4_369_999, true); - vm.roll(block.number + 16_748); - vm.warp(block.timestamp + 4_392_799); + attemptErasureRace(4369999, true); + vm.roll(block.number + 16748); + vm.warp(block.timestamp + 4392799); vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 234 - ); - vm.roll(block.number + 34_563); - vm.warp(block.timestamp + 2_767_272); + registerMembership(11715857356293458169128266324582842123295933765556118813133626045122493941020, 100); + vm.roll(block.number + 34563); + vm.warp(block.timestamp + 2767272); vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, - true - ); - vm.roll(block.number + 28_021); + attemptErasureRace(113494438387109549875854423138737438623578968565768162582136905694666899965063, true); + vm.roll(block.number + 28021); vm.warp(block.timestamp + 24); vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 - ); - vm.roll(block.number + 21_122); - vm.warp(block.timestamp + 6_432_758); + attemptExtensionRace(115369114333842325499285690322288660192694143071536272487538626891694190637069); + vm.roll(block.number + 21122); + vm.warp(block.timestamp + 6432758); vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, - false - ); + attemptErasureRace(95725103252022623036343603958987075634200691826026456898605964745085393962918, false); vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6_842_375); + vm.warp(block.timestamp + 6842375); vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 - ); + attemptExtensionRace(24440054405305269366569402256811496959409073762505157381672968839269610695612); } } From 9fa235571da0ead90056ed07e6a5b0e9d04c6b44 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 28 Oct 2025 18:09:09 +0800 Subject: [PATCH 46/58] fix: test_attemptExtensionRace_WakuRLN --- test/EchidnaReplay.t.sol | 496 ++++++++++++++++++++++++--------------- 1 file changed, 309 insertions(+), 187 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index 387c892..f253842 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -270,269 +270,391 @@ contract EchidnaReplay is Test { } function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59109); - vm.warp(block.timestamp + 12682314); + vm.roll(block.number + 59_109); + vm.warp(block.timestamp + 12_682_314); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(115710044366489380560145754182836127776606905958965281515627230965944185828197, true); - vm.roll(block.number + 35655); - vm.warp(block.timestamp + 15576565); + echidna.attemptErasureRace( + 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, + true + ); + vm.roll(block.number + 35_655); + vm.warp(block.timestamp + 15_576_565); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(12439145154143552525910919713868996066330922688700283373718845930110014852748, 100); + echidna.registerMembership( + 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, 100 + ); vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6585509); + vm.warp(block.timestamp + 6_585_509); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(17390757134860691103601339956017953267743470484370144179061550943820859938352, false); - vm.roll(block.number + 24311); - vm.warp(block.timestamp + 12762680); + echidna.attemptErasureRace( + 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, + false + ); + vm.roll(block.number + 24_311); + vm.warp(block.timestamp + 12_762_680); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(30550828421328047254873089071721340, 100); - vm.roll(block.number + 12819); - vm.warp(block.timestamp + 1649692); + echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 100); + vm.roll(block.number + 12_819); + vm.warp(block.timestamp + 1_649_692); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(104850126800538479521627521813512576589921885869622125078501950362797396775732); - vm.roll(block.number + 45108); - vm.warp(block.timestamp + 1956666); + echidna.attemptExtensionRace( + 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 + ); + vm.roll(block.number + 45_108); + vm.warp(block.timestamp + 1_956_666); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(34886597912158088398731931734494950295345955711258232465783822303829418980034, 100); - vm.roll(block.number + 53007); - vm.warp(block.timestamp + 276592); + echidna.registerMembership( + 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, 100 + ); + vm.roll(block.number + 53_007); + vm.warp(block.timestamp + 276_592); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(834); - vm.roll(block.number + 25848); - vm.warp(block.timestamp + 11362065); + echidna.attemptExtensionRace(834); + vm.roll(block.number + 25_848); + vm.warp(block.timestamp + 11_362_065); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(39174465178587396508459477969368571131696829920441112535821186895419294115835, 100); - vm.roll(block.number + 33171); - vm.warp(block.timestamp + 383675); + echidna.registerMembership( + 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 100 + ); + vm.roll(block.number + 33_171); + vm.warp(block.timestamp + 383_675); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(7022159125197495734384997711896547675021391130223237843255817587255104160363); - vm.roll(block.number + 15676); - vm.warp(block.timestamp + 11735351); + echidna.attemptExtensionRace( + 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 + ); + vm.roll(block.number + 15_676); + vm.warp(block.timestamp + 11_735_351); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(101185480181713116242457669701483883593620024991591651269453671853652437478102); - vm.roll(block.number + 44384); - vm.warp(block.timestamp + 18346179); + echidna.attemptExtensionRace( + 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 + ); + vm.roll(block.number + 44_384); + vm.warp(block.timestamp + 18_346_179); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(4908416131442887573991189028182614782884545304889259793974797565686968097292, 100); - vm.roll(block.number + 16801); - vm.warp(block.timestamp + 573740); + echidna.registerMembership( + 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, 100 + ); + vm.roll(block.number + 16_801); + vm.warp(block.timestamp + 573_740); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639933, 100); - vm.roll(block.number + 35654); - vm.warp(block.timestamp + 4068035); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, 100 + ); + vm.roll(block.number + 35_654); + vm.warp(block.timestamp + 4_068_035); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(18978082967849498068717608127246258727629855559346799025101476822814831852169); - vm.roll(block.number + 30101); - vm.warp(block.timestamp + 4745968); + echidna.attemptExtensionRace( + 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 + ); + vm.roll(block.number + 30_101); + vm.warp(block.timestamp + 4_745_968); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(6106105733994696914590284712692); + echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14763861); + vm.warp(block.timestamp + 14_763_861); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(104237522040539086529385814200395911913667236478153241258910237150016100933281); - vm.roll(block.number + 52780); - vm.warp(block.timestamp + 16427024); + echidna.attemptExtensionRace( + 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 + ); + vm.roll(block.number + 52_780); + vm.warp(block.timestamp + 16_427_024); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(8555773188090352132903209190922658630799967488207010664039959647283030053950, 100); - vm.roll(block.number + 36392); - vm.warp(block.timestamp + 11470167); + echidna.registerMembership( + 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, 100 + ); + vm.roll(block.number + 36_392); + vm.warp(block.timestamp + 11_470_167); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(9394776414966240069580838672673694685292165040808226440647796406499139370962, true); - vm.roll(block.number + 13355); - vm.warp(block.timestamp + 16427025); + echidna.attemptErasureRace( + 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true + ); + vm.roll(block.number + 13_355); + vm.warp(block.timestamp + 16_427_025); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(9630707582521938235113899367442877106957117302212260601089037887382200262601, false); - vm.roll(block.number + 22867); - vm.warp(block.timestamp + 159999); + echidna.attemptErasureRace( + 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false + ); + vm.roll(block.number + 22_867); + vm.warp(block.timestamp + 159_999); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(28243736643972833793366231626843204992644487197555289924254482104591589940922); - vm.roll(block.number + 22820); - vm.warp(block.timestamp + 4779059); + echidna.attemptExtensionRace( + 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 + ); + vm.roll(block.number + 22_820); + vm.warp(block.timestamp + 4_779_059); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(19201590924623513311141753466125212569043677014481753075022686585593991810749, 100); - vm.roll(block.number + 35266); - vm.warp(block.timestamp + 3182076); + echidna.registerMembership( + 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, 100 + ); + vm.roll(block.number + 35_266); + vm.warp(block.timestamp + 3_182_076); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(43827548018134037042906582304483527074537881763084930140765111011615661349666); - vm.roll(block.number + 19490); - vm.warp(block.timestamp + 299200); + echidna.attemptExtensionRace( + 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 + ); + vm.roll(block.number + 19_490); + vm.warp(block.timestamp + 299_200); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(12776298811140222029408960445729157525018582422120161448937390282915768616624); - vm.roll(block.number + 51788); - vm.warp(block.timestamp + 18651487); + echidna.attemptExtensionRace( + 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 + ); + vm.roll(block.number + 51_788); + vm.warp(block.timestamp + 18_651_487); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(107301127263897597227628761122806603306606929334009477725205515511615612118148, true); - vm.roll(block.number + 49348); - vm.warp(block.timestamp + 12337026); + echidna.attemptErasureRace( + 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, + true + ); + vm.roll(block.number + 49_348); + vm.warp(block.timestamp + 12_337_026); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(14744269619966411208579211824598458697587494354926760081771325075741142829158, 100); - vm.roll(block.number + 49829); - vm.warp(block.timestamp + 12713084); + echidna.registerMembership( + 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, 100 + ); + vm.roll(block.number + 49_829); + vm.warp(block.timestamp + 12_713_084); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(43792367251478649051155053078982380795888842184379994324460592762045082390946); + echidna.attemptExtensionRace( + 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 + ); vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14763856); + vm.warp(block.timestamp + 14_763_856); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(828, true); - vm.roll(block.number + 36651); - vm.warp(block.timestamp + 4476578); + echidna.attemptErasureRace(828, true); + vm.roll(block.number + 36_651); + vm.warp(block.timestamp + 4_476_578); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115046885519045122606446282744980637739795881293862923481580204068197516138270, false); - vm.roll(block.number + 41972); - vm.warp(block.timestamp + 15765194); + echidna.attemptErasureRace( + 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, + false + ); + vm.roll(block.number + 41_972); + vm.warp(block.timestamp + 15_765_194); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(7171889270225471948987523104033632910444398328090760036609063776968837717794, true); - vm.roll(block.number + 12338); - vm.warp(block.timestamp + 16542398); + echidna.attemptErasureRace( + 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true + ); + vm.roll(block.number + 12_338); + vm.warp(block.timestamp + 16_542_398); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(36820031792293339223546668816467201710704202917197104615399587045614220405399, 100); - vm.roll(block.number + 21241); - vm.warp(block.timestamp + 1018641); + echidna.registerMembership( + 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, 100 + ); + vm.roll(block.number + 21_241); + vm.warp(block.timestamp + 1_018_641); vm.prank(0x0000000000000000000000000000000000010000); - registerMembership(77752533705984083621774514325091611770137972395322818578120871980142243088871, 100); // Updated to 100 for consistency - vm.roll(block.number + 19489); - vm.warp(block.timestamp + 2368987); + echidna.registerMembership( + 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 100 + ); // Updated to 100 for consistency + vm.roll(block.number + 19_489); + vm.warp(block.timestamp + 2_368_987); vm.prank(0x0000000000000000000000000000000000030000); - registerMembership(4014188762916583598888942667424965430287497824629657219807941460227372577779, 100); // Updated - vm.roll(block.number + 50607); - vm.warp(block.timestamp + 6275598); + echidna.registerMembership( + 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 + ); // Updated + vm.roll(block.number + 50_607); + vm.warp(block.timestamp + 6_275_598); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(25686798737320918646636587445932741319837891759549806387798392338795533488010); - vm.roll(block.number + 32528); - vm.warp(block.timestamp + 11364405); + echidna.attemptExtensionRace( + 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 + ); + vm.roll(block.number + 32_528); + vm.warp(block.timestamp + 11_364_405); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(53991267514590793278297355948559624755148862080273380827299810595369156972613, 100); - vm.roll(block.number + 34897); - vm.warp(block.timestamp + 7243908); + echidna.registerMembership( + 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, 100 + ); + vm.roll(block.number + 34_897); + vm.warp(block.timestamp + 7_243_908); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(14593453114436356872569019099482380600010961031449147888385564231161572479533, false); - vm.roll(block.number + 32012); - vm.warp(block.timestamp + 4454946); + echidna.attemptErasureRace( + 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, + false + ); + vm.roll(block.number + 32_012); + vm.warp(block.timestamp + 4_454_946); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(25925918697093082051988700719536417857215502310699420143298508813462032862395); - vm.roll(block.number + 28697); - vm.warp(block.timestamp + 15970432); + echidna.attemptExtensionRace( + 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 + ); + vm.roll(block.number + 28_697); + vm.warp(block.timestamp + 15_970_432); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(108479333139474050100903533488798991877708572455902122277366214901308705838858, 100); - vm.roll(block.number + 14898); - vm.warp(block.timestamp + 4838522); + echidna.registerMembership( + 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, 100 + ); + vm.roll(block.number + 14_898); + vm.warp(block.timestamp + 4_838_522); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639932, false); - vm.roll(block.number + 19847); - vm.warp(block.timestamp + 14942829); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, + false + ); + vm.roll(block.number + 19_847); + vm.warp(block.timestamp + 14_942_829); vm.prank(0x0000000000000000000000000000000000010000); - attemptErasureRace(70301009613960490917949744526391086498442689163222427992725693722994258137973, false); - vm.roll(block.number + 12155); - vm.warp(block.timestamp + 14219479); + echidna.attemptErasureRace( + 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, + false + ); + vm.roll(block.number + 12_155); + vm.warp(block.timestamp + 14_219_479); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(76966217218353830958442135212923621112975360884156253028656115159618856313417); + echidna.attemptExtensionRace( + 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 + ); vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287808); + vm.warp(block.timestamp + 287_808); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639933, true); - vm.roll(block.number + 34448); - vm.warp(block.timestamp + 7211969); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, + true + ); + vm.roll(block.number + 34_448); + vm.warp(block.timestamp + 7_211_969); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639912, false); - vm.roll(block.number + 16001); - vm.warp(block.timestamp + 18874761); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, + false + ); + vm.roll(block.number + 16_001); + vm.warp(block.timestamp + 18_874_761); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639931, true); - vm.roll(block.number + 37485); - vm.warp(block.timestamp + 11975371); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, + true + ); + vm.roll(block.number + 37_485); + vm.warp(block.timestamp + 11_975_371); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(37335511784273848537689431468682439708817559909961396759913669152336630041800); - vm.roll(block.number + 52321); - vm.warp(block.timestamp + 18466804); + echidna.attemptExtensionRace( + 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 + ); + vm.roll(block.number + 52_321); + vm.warp(block.timestamp + 18_466_804); vm.prank(0x0000000000000000000000000000000000020000); - attemptErasureRace(477, false); - vm.roll(block.number + 31665); - vm.warp(block.timestamp + 373007); + echidna.attemptErasureRace(477, false); + vm.roll(block.number + 31_665); + vm.warp(block.timestamp + 373_007); vm.prank(0x0000000000000000000000000000000000030000); - registerMembership(82544183440599290253901529097973022858563960899075426055988440093036240231550, 100); - vm.roll(block.number + 45111); - vm.warp(block.timestamp + 15500872); + echidna.registerMembership( + 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 100 + ); + vm.roll(block.number + 45_111); + vm.warp(block.timestamp + 15_500_872); vm.prank(0x0000000000000000000000000000000000030000); - attemptExtensionRace(105606550632292314621503518143649535828775273028210522109286717639175153183420); - vm.roll(block.number + 36506); - vm.warp(block.timestamp + 7414210); + echidna.attemptExtensionRace( + 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 + ); + vm.roll(block.number + 36_506); + vm.warp(block.timestamp + 7_414_210); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(161, 100); - vm.roll(block.number + 56897); - vm.warp(block.timestamp + 12441897); + echidna.registerMembership(161, 100); + vm.roll(block.number + 56_897); + vm.warp(block.timestamp + 12_441_897); vm.prank(0x0000000000000000000000000000000000010000); - attemptErasureRace(111398094352181033884768016817884715635237389508840493420231528590208237700862, false); + echidna.attemptErasureRace( + 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, + false + ); vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16471434); + vm.warp(block.timestamp + 16_471_434); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(105337060722689913614253553269990692457515092424074600138749804416711343223382); + echidna.attemptExtensionRace( + 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 + ); vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1922225); + vm.warp(block.timestamp + 1_922_225); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(18872386506188900128178593638530871606212752948544745205989878007158625800496); - vm.roll(block.number + 15232); - vm.warp(block.timestamp + 6674678); + echidna.attemptExtensionRace( + 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 + ); + vm.roll(block.number + 15_232); + vm.warp(block.timestamp + 6_674_678); vm.prank(0x0000000000000000000000000000000000040000); - attemptExtensionRace(4009354985947816657442120275607); - vm.roll(block.number + 48756); - vm.warp(block.timestamp + 10087875); + echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); + vm.roll(block.number + 48_756); + vm.warp(block.timestamp + 10_087_875); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(69); - vm.roll(block.number + 38102); - vm.warp(block.timestamp + 15788002); + echidna.attemptExtensionRace(69); + vm.roll(block.number + 38_102); + vm.warp(block.timestamp + 15_788_002); vm.prank(0x0000000000000000000000000000000000020000); - registerMembership(18840924862590752659304250828416640310422888056457367520753407434927494649451, 100); + echidna.registerMembership( + 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, 100 + ); vm.roll(block.number + 5750); vm.warp(block.timestamp + 2503); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(426281677759936592021316809065178817848084678679510574715894138690250139747, false); - vm.roll(block.number + 21989); - vm.warp(block.timestamp + 4979832); + echidna.attemptErasureRace( + 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false + ); + vm.roll(block.number + 21_989); + vm.warp(block.timestamp + 4_979_832); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(21853424399738097885762888601689700621597911601971608617330124755808946442755, true); - vm.roll(block.number + 50175); - vm.warp(block.timestamp + 2618050); + echidna.attemptErasureRace( + 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true + ); + vm.roll(block.number + 50_175); + vm.warp(block.timestamp + 2_618_050); vm.prank(0x0000000000000000000000000000000000010000); - registerMembership(880, 100); - vm.roll(block.number + 44581); - vm.warp(block.timestamp + 18429750); + echidna.registerMembership(880, 100); + vm.roll(block.number + 44_581); + vm.warp(block.timestamp + 18_429_750); vm.prank(0x0000000000000000000000000000000000040000); - registerMembership(115792089237316195423570985008687907853269984665640564039457584007913129639934, 100); - vm.roll(block.number + 25967); - vm.warp(block.timestamp + 2753174); + echidna.registerMembership( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, 100 + ); + vm.roll(block.number + 25_967); + vm.warp(block.timestamp + 2_753_174); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(451); + echidna.attemptExtensionRace(451); vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11364502); + vm.warp(block.timestamp + 11_364_502); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(115792089237316195423570985008687907853269984665640564039457584007913129639934, false); - vm.roll(block.number + 11905); - vm.warp(block.timestamp + 11497582); + echidna.attemptErasureRace( + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, + false + ); + vm.roll(block.number + 11_905); + vm.warp(block.timestamp + 11_497_582); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(20); - vm.roll(block.number + 51936); - vm.warp(block.timestamp + 11362064); + echidna.attemptExtensionRace(20); + vm.roll(block.number + 51_936); + vm.warp(block.timestamp + 11_362_064); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(4369999, true); - vm.roll(block.number + 16748); - vm.warp(block.timestamp + 4392799); + echidna.attemptErasureRace(4_369_999, true); + vm.roll(block.number + 16_748); + vm.warp(block.timestamp + 4_392_799); vm.prank(0x0000000000000000000000000000000000030000); - registerMembership(11715857356293458169128266324582842123295933765556118813133626045122493941020, 100); - vm.roll(block.number + 34563); - vm.warp(block.timestamp + 2767272); + echidna.registerMembership( + 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 100 + ); + vm.roll(block.number + 34_563); + vm.warp(block.timestamp + 2_767_272); vm.prank(0x0000000000000000000000000000000000040000); - attemptErasureRace(113494438387109549875854423138737438623578968565768162582136905694666899965063, true); - vm.roll(block.number + 28021); + echidna.attemptErasureRace( + 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, + true + ); + vm.roll(block.number + 28_021); vm.warp(block.timestamp + 24); vm.prank(0x0000000000000000000000000000000000010000); - attemptExtensionRace(115369114333842325499285690322288660192694143071536272487538626891694190637069); - vm.roll(block.number + 21122); - vm.warp(block.timestamp + 6432758); + echidna.attemptExtensionRace( + 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 + ); + vm.roll(block.number + 21_122); + vm.warp(block.timestamp + 6_432_758); vm.prank(0x0000000000000000000000000000000000030000); - attemptErasureRace(95725103252022623036343603958987075634200691826026456898605964745085393962918, false); + echidna.attemptErasureRace( + 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, + false + ); vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6842375); + vm.warp(block.timestamp + 6_842_375); vm.prank(0x0000000000000000000000000000000000020000); - attemptExtensionRace(24440054405305269366569402256811496959409073762505157381672968839269610695612); + echidna.attemptExtensionRace( + 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 + ); } } From 4ac19d2d20a6830101c6d0951093a714f5337da5 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 13:37:13 +0800 Subject: [PATCH 47/58] fix: invalid commitment in test_attemptExtensionRace_WakuRLN --- test/EchidnaReplay.t.sol | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index f253842..f37c5cb 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -304,8 +304,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 1_956_666); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 34_886_597_912_158_088_398_731_931_734_494_950_295_345_955_711_258_232_465_783_822_303_829_418_980_034, 100 - ); + 12_998_355_040_318_813_176_485_525_989_237_675_206_797_591_310_842_198_122_085_618_117_253_610_484_417, 100 + ); // Changed commitment vm.roll(block.number + 53_007); vm.warp(block.timestamp + 276_592); vm.prank(0x0000000000000000000000000000000000040000); @@ -314,8 +314,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 11_362_065); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 39_174_465_178_587_396_508_459_477_969_368_571_131_696_829_920_441_112_535_821_186_895_419_294_115_835, 100 - ); + 17_286_222_306_748_121_286_213_072_224_111_296_043_148_465_520_025_078_192_122_982_708_843_485_620_218, 100 + ); // Changed commitment vm.roll(block.number + 33_171); vm.warp(block.timestamp + 383_675); vm.prank(0x0000000000000000000000000000000000040000); @@ -338,7 +338,7 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 573_740); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, 100 + 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_848, 100 ); vm.roll(block.number + 35_654); vm.warp(block.timestamp + 4_068_035); @@ -438,20 +438,20 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 16_542_398); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 36_820_031_792_293_339_223_546_668_816_467_201_710_704_202_917_197_104_615_399_587_045_614_220_405_399, 100 - ); + 14_931_788_920_454_064_001_300_263_071_209_926_622_155_838_516_781_070_271_701_382_859_038_411_909_782, 100 + ); // Changed commitment vm.roll(block.number + 21_241); vm.warp(block.timestamp + 1_018_641); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 77_752_533_705_984_083_621_774_514_325_091_611_770_137_972_395_322_818_578_120_871_980_142_243_088_871, 100 - ); // Updated to 100 for consistency + 12_087_805_090_466_257_955_035_297_089_319_786_504_492_879_194_074_715_547_026_259_420_414_817_602_020, 100 + ); // Changed commitment vm.roll(block.number + 19_489); vm.warp(block.timestamp + 2_368_987); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 - ); // Updated + ); vm.roll(block.number + 50_607); vm.warp(block.timestamp + 6_275_598); vm.prank(0x0000000000000000000000000000000000010000); @@ -462,8 +462,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 11_364_405); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 53_991_267_514_590_793_278_297_355_948_559_624_755_148_862_080_273_380_827_299_810_595_369_156_972_613, 100 - ); + 10_214_781_770_912_242_833_804_544_458_045_074_578_052_133_279_441_312_139_903_402_222_217_539_981_379, 100 + ); // Changed commitment vm.roll(block.number + 34_897); vm.warp(block.timestamp + 7_243_908); vm.prank(0x0000000000000000000000000000000000020000); @@ -481,8 +481,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 15_970_432); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 108_479_333_139_474_050_100_903_533_488_798_991_877_708_572_455_902_122_277_366_214_901_308_705_838_858, 100 - ); + 20_926_361_652_116_949_211_917_910_507_769_891_523_515_114_854_237_984_902_573_398_155_005_471_856_390, 100 + ); // Changed commitment vm.roll(block.number + 14_898); vm.warp(block.timestamp + 4_838_522); vm.prank(0x0000000000000000000000000000000000020000); @@ -538,8 +538,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 373_007); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 82_544_183_440_599_290_253_901_529_097_973_022_858_563_960_899_075_426_055_988_440_093_036_240_231_550, 100 - ); + 16_879_454_825_081_464_587_162_311_862_201_197_592_918_867_697_827_323_024_893_827_533_308_814_744_699, 100 + ); // Changed commitment vm.roll(block.number + 45_111); vm.warp(block.timestamp + 15_500_872); vm.prank(0x0000000000000000000000000000000000030000); @@ -603,8 +603,8 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 18_429_750); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, 100 - ); + 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_849, 100 + ); // Changed commitment vm.roll(block.number + 25_967); vm.warp(block.timestamp + 2_753_174); vm.prank(0x0000000000000000000000000000000000020000); From f48a95be30d7ab74daf46a27f21bc02ddec6970d Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 14:45:03 +0800 Subject: [PATCH 48/58] fix: invalid commitments in test_attemptErasureRace_WakuRLN --- test/EchidnaReplay.t.sol | 42 +++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index f37c5cb..aaa4337 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -18,28 +18,33 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 5_474_623); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 15_331_181_254_680_049_984_374_210_433_775_713_530_849_624_954_688_899_814_297_733_641_575_188_164_316, - 1_002_356_836 + 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, // Valid + // Baby Jubjub point x + 100 // Reduced duration ); vm.roll(block.number + 47_085); vm.warp(block.timestamp + 9_714_873); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 57_443_432_183_176_588_916_867_111_037_381_903_541_553_297_067_891_717_016_451_751_957_342_384_738_336, - 160_001 + 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, // Valid + // Baby Jubjub point y (used as x for variety) + 100 // Reduced duration ); vm.roll(block.number + 38_103); vm.warp(block.timestamp + 4_558_906); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 102_920_729_880_426_261_698_536_426_573_884_612_971_230_188_871_291_431_396_182_739_877_428_962_960_239, - 2_847_778_459 + 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, // From + // signature R x + 100 // Reduced duration ); vm.roll(block.number + 29_746); vm.warp(block.timestamp + 13_228_720); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 86_642_110_490_369_375_485_379_969_193_766_212_650_854_355_737_426_080_322_527_445_883_017_455_452_642, 4 + 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, // From + // signature R y + 100 // Reduced duration ); vm.roll(block.number + 58_772); vm.warp(block.timestamp + 16_726_535); @@ -121,56 +126,49 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 1); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, - 23_935_070 + 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, 100 ); vm.roll(block.number + 46_636); vm.warp(block.timestamp + 11_821_678); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, - 1_190_462_738 + 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, 100 ); vm.roll(block.number + 57_888); vm.warp(block.timestamp + 11_470_172); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, - 425_830_326 + 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, 100 ); vm.roll(block.number + 53_678); vm.warp(block.timestamp + 1_059_409); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, - 1_532_892_061 + 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, 100 ); vm.roll(block.number + 9163); vm.warp(block.timestamp + 5_088_962); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, - 1_578_212_921 + 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, 100 ); vm.roll(block.number + 57_370); vm.warp(block.timestamp + 7_211_971); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 597 + 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 100 ); vm.roll(block.number + 52_325); vm.warp(block.timestamp + 7_269_956); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, - 359_384_427 + 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, 100 ); vm.roll(block.number + 13); vm.warp(block.timestamp + 11_809_403); vm.prank(0x0000000000000000000000000000000000030000); echidna.registerMembership( - 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, - 15_551_999 + 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, 100 ); vm.roll(block.number + 50_167); vm.warp(block.timestamp + 10_228_636); From 5d80fabd5ab74eb9db0592b76cdc572c12c5dd68 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 29 Oct 2025 14:57:42 +0800 Subject: [PATCH 49/58] fix: line length --- test/EchidnaReplay.t.sol | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol index aaa4337..5361628 100644 --- a/test/EchidnaReplay.t.sol +++ b/test/EchidnaReplay.t.sol @@ -18,33 +18,37 @@ contract EchidnaReplay is Test { vm.warp(block.timestamp + 5_474_623); vm.prank(0x0000000000000000000000000000000000020000); echidna.registerMembership( - 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, // Valid - // Baby Jubjub point x - 100 // Reduced duration + // Valid Baby Jubjub point x + 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, + // Reduced duration + 100 ); vm.roll(block.number + 47_085); vm.warp(block.timestamp + 9_714_873); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, // Valid - // Baby Jubjub point y (used as x for variety) - 100 // Reduced duration + // Valid Baby Jubjub point y (used as x for variety) + 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, + // Reduced duration + 100 ); vm.roll(block.number + 38_103); vm.warp(block.timestamp + 4_558_906); vm.prank(0x0000000000000000000000000000000000010000); echidna.registerMembership( - 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, // From - // signature R x - 100 // Reduced duration + // From signature R x + 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, + // Reduced duration + 100 ); vm.roll(block.number + 29_746); vm.warp(block.timestamp + 13_228_720); vm.prank(0x0000000000000000000000000000000000040000); echidna.registerMembership( - 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, // From - // signature R y - 100 // Reduced duration + // From signature R y + 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, + // Reduced duration + 100 ); vm.roll(block.number + 58_772); vm.warp(block.timestamp + 16_726_535); From be79a4d14524a6fac5cc0d02eaef4f51bb6193b5 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 7 Nov 2025 09:40:33 +0800 Subject: [PATCH 50/58] fix: cleanup after rebase --- test/EchidnaReplay.t.sol | 662 ------------------------------------ test/EchidnaTestRaces.t.sol | 31 -- 2 files changed, 693 deletions(-) delete mode 100644 test/EchidnaReplay.t.sol diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol deleted file mode 100644 index 5361628..0000000 --- a/test/EchidnaReplay.t.sol +++ /dev/null @@ -1,662 +0,0 @@ -pragma solidity 0.8.24; - -// Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna -// Assume EchidnaTest.sol is the Echidna harness contract that defines the methods like registerMembership, -// attemptExtensionRace, attemptErasureRace. -import "./EchidnaTest.t.sol"; -import "forge-std/Test.sol"; // Replace with the actual path to EchidnaTest.sol - -contract EchidnaReplay is Test { - EchidnaTest internal echidna; - - function setUp() public { - echidna = new EchidnaTest(); - } - - function test_attemptErasureRace_WakuRLN() public { - vm.roll(block.number + 11_796); - vm.warp(block.timestamp + 5_474_623); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - // Valid Baby Jubjub point x - 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, - // Reduced duration - 100 - ); - vm.roll(block.number + 47_085); - vm.warp(block.timestamp + 9_714_873); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - // Valid Baby Jubjub point y (used as x for variety) - 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, - // Reduced duration - 100 - ); - vm.roll(block.number + 38_103); - vm.warp(block.timestamp + 4_558_906); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - // From signature R x - 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, - // Reduced duration - 100 - ); - vm.roll(block.number + 29_746); - vm.warp(block.timestamp + 13_228_720); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - // From signature R y - 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, - // Reduced duration - 100 - ); - vm.roll(block.number + 58_772); - vm.warp(block.timestamp + 16_726_535); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933 - ); - vm.roll(block.number + 48_493); - vm.warp(block.timestamp + 1_204_344); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_231_738_780_016_212_060_605_121_782_152_175_650_399_916_271_686_623_479_564_981_844_592_372_633_495 - ); - vm.roll(block.number + 36_902); - vm.warp(block.timestamp + 6_674_673); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 14_271_763_308_400_718_165_336_499_097_156_975_241_954_733_520_325_982_997_864_342_600_795_471_836_727 - ); - vm.roll(block.number + 33_845); - vm.warp(block.timestamp + 735_716); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 9_999_044_003_322_463_509_208_400_801_275_356_671_266_978_396_985_433_172_455_084_837_770_460_579_628 - ); - vm.roll(block.number + 35_781); - vm.warp(block.timestamp + 15_419_955); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 14_868_750_298_864_215_918_931_212_669_461_480_940_838_279_805_163_953_554_392_700_481_114_788_988_217 - ); - vm.roll(block.number + 771); - vm.warp(block.timestamp + 17_913_418); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(15_552_001, false); - vm.roll(block.number + 18_055); - vm.warp(block.timestamp + 13_187_508); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 4_498_454_914_711_882_268_466_328_398_075_690_403_183_913_761_650_565_928_933_850_043_231_959_582_090 - ); - vm.roll(block.number + 44_293); - vm.warp(block.timestamp + 11_359_790); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(8_816_298_471_565_553_478_253); - vm.roll(block.number + 53_425); - vm.warp(block.timestamp + 4_444_562); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 745_203_718_271_072_817_124_702_263_707_270_113_474_103_371_777_640_557_877_379_939_715_613_501_666 - ); - vm.roll(block.number + 33_562); - vm.warp(block.timestamp + 14_219_475); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 106_881_024_749_878_243_321_292_280_200_974_139_959_817_939_173_788_106_633_056_826_054_874_002_347_673, - false - ); - vm.roll(block.number + 51_795); - vm.warp(block.timestamp + 16_733_054); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 810_181_532_076_738_148_308_457_416_289_197_585_577_119_693_706_380_535_394_811_298_325_092_337_779, true - ); - vm.roll(block.number + 52_386); - vm.warp(block.timestamp + 13_340_960); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 39_191_598_377_141_549_315_856_730_925_567_207_940_583_071_046_522_612_928_475_157_163_375_553_445_883, - false - ); - vm.roll(block.number + 28_778); - vm.warp(block.timestamp + 19_485_372); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 422_974_903_473_869_924_285_294_686_399_247_660_575_841_594_104_291_551_918_957_116_218_939_002_862 - ); - vm.roll(block.number + 53_838); - vm.warp(block.timestamp + 1); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, 100 - ); - vm.roll(block.number + 46_636); - vm.warp(block.timestamp + 11_821_678); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, 100 - ); - vm.roll(block.number + 57_888); - vm.warp(block.timestamp + 11_470_172); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, 100 - ); - vm.roll(block.number + 53_678); - vm.warp(block.timestamp + 1_059_409); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, 100 - ); - vm.roll(block.number + 9163); - vm.warp(block.timestamp + 5_088_962); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, 100 - ); - vm.roll(block.number + 57_370); - vm.warp(block.timestamp + 7_211_971); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 100 - ); - vm.roll(block.number + 52_325); - vm.warp(block.timestamp + 7_269_956); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, 100 - ); - vm.roll(block.number + 13); - vm.warp(block.timestamp + 11_809_403); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, 100 - ); - vm.roll(block.number + 50_167); - vm.warp(block.timestamp + 10_228_636); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 907_529_701_442_527_636_822_361_196_151_011_186_835_477_052_160_076_110_045_266_796_422_655_750 - ); - vm.roll(block.number + 32_448); - vm.warp(block.timestamp + 6_071_296); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 36_152_006_575_898_071_413_738_485_534_610_504_772_123_181_747_755_834_736_036_287_698_777_015_184_002, - false - ); - vm.roll(block.number + 6729); - vm.warp(block.timestamp + 5_889_939); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 58_463_562_426_656_549_831_725_639_173_426_781_888_371_207_839_773_191_116_779_676_742_569_157_617_676, true - ); - vm.roll(block.number + 49_403); - vm.warp(block.timestamp + 14_818_957); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932 - ); - vm.roll(block.number + 44_385); - vm.warp(block.timestamp + 7_821_507); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 111_185_342_898_521_325_588_224_305_609_230_586_551_748_536_155_220_651_814_001_626_697_158_870_944_491, - false - ); - vm.roll(block.number + 8138); - vm.warp(block.timestamp + 3_986_838); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 5_563_317_320_536_360_357_019_805_881_367_133_322_562_055_054_443_943_486_481_491_020_841_431_450_882, true - ); - vm.roll(block.number + 55_495); - vm.warp(block.timestamp + 13_298_744); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 82_150_570_835_311_748_779_613_601_590_930_899_007_637_956_995_391_819_623_786_983_419_155_333_240_346, - false - ); - vm.roll(block.number + 53_808); - vm.warp(block.timestamp + 16_113_649); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 94_756_843_913_980_367_703_825_440_635_606_010_870_107_150_061_183_736_341_168_934_719_085_836_060_272 - ); - vm.roll(block.number + 53_575); - vm.warp(block.timestamp + 6_685_351); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 22_524_513_599_250_775_770_561_496_810_744_347_426_238_296_396_541_115_644_891_258_189_615_473_070_435, - false - ); - vm.roll(block.number + 35_363); - vm.warp(block.timestamp + 5_418_157); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 89_833_576_623_011_348_753_034_902_489_203_339_405_860_111_267_468_969_771_441_095_409_308_430_642_032, 61 - ); - vm.roll(block.number + 2914); - vm.warp(block.timestamp + 7_963_431); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 2_555_752_030_748_925_341_265_856_133_642_532_487_884_589_978_209_403_118_872_788_051_695_546_807_405, 20 - ); - vm.roll(block.number + 42_147); - vm.warp(block.timestamp + 11_043_183); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 114_754_453_626_733_198_273_777_522_719_098_112_979_869_218_458_062_538_485_135_739_426_192_996_542_208, 36 - ); - vm.roll(block.number + 4708); - vm.warp(block.timestamp + 11_691_783); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 104_896_750_968_454_172_725_482_821_202_386_350_664_629_961_052_485_242_745_091_802_526_249_639_802_019 - ); - vm.roll(block.number + 59_035); - vm.warp(block.timestamp + 11_364_443); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 46_890_934_969_458_242_237_056_668_330_086_728_522_184_233_411_179_055_912_131_707_524_887_240_413_667, 64 - ); - vm.roll(block.number + 59_751); - vm.warp(block.timestamp + 6_021_229); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 108_620_199_967_090_723_474_583_461_904_654_274_942_825_586_337_549_804_002_848_520_230_944_291_922_140, - true - ); - } - - function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59_109); - vm.warp(block.timestamp + 12_682_314); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, - true - ); - vm.roll(block.number + 35_655); - vm.warp(block.timestamp + 15_576_565); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, 100 - ); - vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6_585_509); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, - false - ); - vm.roll(block.number + 24_311); - vm.warp(block.timestamp + 12_762_680); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 100); - vm.roll(block.number + 12_819); - vm.warp(block.timestamp + 1_649_692); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 - ); - vm.roll(block.number + 45_108); - vm.warp(block.timestamp + 1_956_666); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_998_355_040_318_813_176_485_525_989_237_675_206_797_591_310_842_198_122_085_618_117_253_610_484_417, 100 - ); // Changed commitment - vm.roll(block.number + 53_007); - vm.warp(block.timestamp + 276_592); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(834); - vm.roll(block.number + 25_848); - vm.warp(block.timestamp + 11_362_065); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 17_286_222_306_748_121_286_213_072_224_111_296_043_148_465_520_025_078_192_122_982_708_843_485_620_218, 100 - ); // Changed commitment - vm.roll(block.number + 33_171); - vm.warp(block.timestamp + 383_675); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 - ); - vm.roll(block.number + 15_676); - vm.warp(block.timestamp + 11_735_351); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 - ); - vm.roll(block.number + 44_384); - vm.warp(block.timestamp + 18_346_179); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, 100 - ); - vm.roll(block.number + 16_801); - vm.warp(block.timestamp + 573_740); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_848, 100 - ); - vm.roll(block.number + 35_654); - vm.warp(block.timestamp + 4_068_035); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 - ); - vm.roll(block.number + 30_101); - vm.warp(block.timestamp + 4_745_968); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); - vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14_763_861); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 - ); - vm.roll(block.number + 52_780); - vm.warp(block.timestamp + 16_427_024); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, 100 - ); - vm.roll(block.number + 36_392); - vm.warp(block.timestamp + 11_470_167); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true - ); - vm.roll(block.number + 13_355); - vm.warp(block.timestamp + 16_427_025); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false - ); - vm.roll(block.number + 22_867); - vm.warp(block.timestamp + 159_999); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 - ); - vm.roll(block.number + 22_820); - vm.warp(block.timestamp + 4_779_059); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, 100 - ); - vm.roll(block.number + 35_266); - vm.warp(block.timestamp + 3_182_076); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 - ); - vm.roll(block.number + 19_490); - vm.warp(block.timestamp + 299_200); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 - ); - vm.roll(block.number + 51_788); - vm.warp(block.timestamp + 18_651_487); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, - true - ); - vm.roll(block.number + 49_348); - vm.warp(block.timestamp + 12_337_026); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, 100 - ); - vm.roll(block.number + 49_829); - vm.warp(block.timestamp + 12_713_084); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 - ); - vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14_763_856); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(828, true); - vm.roll(block.number + 36_651); - vm.warp(block.timestamp + 4_476_578); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, - false - ); - vm.roll(block.number + 41_972); - vm.warp(block.timestamp + 15_765_194); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true - ); - vm.roll(block.number + 12_338); - vm.warp(block.timestamp + 16_542_398); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 14_931_788_920_454_064_001_300_263_071_209_926_622_155_838_516_781_070_271_701_382_859_038_411_909_782, 100 - ); // Changed commitment - vm.roll(block.number + 21_241); - vm.warp(block.timestamp + 1_018_641); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 12_087_805_090_466_257_955_035_297_089_319_786_504_492_879_194_074_715_547_026_259_420_414_817_602_020, 100 - ); // Changed commitment - vm.roll(block.number + 19_489); - vm.warp(block.timestamp + 2_368_987); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 - ); - vm.roll(block.number + 50_607); - vm.warp(block.timestamp + 6_275_598); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 - ); - vm.roll(block.number + 32_528); - vm.warp(block.timestamp + 11_364_405); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 10_214_781_770_912_242_833_804_544_458_045_074_578_052_133_279_441_312_139_903_402_222_217_539_981_379, 100 - ); // Changed commitment - vm.roll(block.number + 34_897); - vm.warp(block.timestamp + 7_243_908); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, - false - ); - vm.roll(block.number + 32_012); - vm.warp(block.timestamp + 4_454_946); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 - ); - vm.roll(block.number + 28_697); - vm.warp(block.timestamp + 15_970_432); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 20_926_361_652_116_949_211_917_910_507_769_891_523_515_114_854_237_984_902_573_398_155_005_471_856_390, 100 - ); // Changed commitment - vm.roll(block.number + 14_898); - vm.warp(block.timestamp + 4_838_522); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, - false - ); - vm.roll(block.number + 19_847); - vm.warp(block.timestamp + 14_942_829); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, - false - ); - vm.roll(block.number + 12_155); - vm.warp(block.timestamp + 14_219_479); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 - ); - vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287_808); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - true - ); - vm.roll(block.number + 34_448); - vm.warp(block.timestamp + 7_211_969); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, - false - ); - vm.roll(block.number + 16_001); - vm.warp(block.timestamp + 18_874_761); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, - true - ); - vm.roll(block.number + 37_485); - vm.warp(block.timestamp + 11_975_371); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 - ); - vm.roll(block.number + 52_321); - vm.warp(block.timestamp + 18_466_804); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace(477, false); - vm.roll(block.number + 31_665); - vm.warp(block.timestamp + 373_007); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 16_879_454_825_081_464_587_162_311_862_201_197_592_918_867_697_827_323_024_893_827_533_308_814_744_699, 100 - ); // Changed commitment - vm.roll(block.number + 45_111); - vm.warp(block.timestamp + 15_500_872); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 - ); - vm.roll(block.number + 36_506); - vm.warp(block.timestamp + 7_414_210); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership(161, 100); - vm.roll(block.number + 56_897); - vm.warp(block.timestamp + 12_441_897); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, - false - ); - vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16_471_434); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 - ); - vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1_922_225); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 - ); - vm.roll(block.number + 15_232); - vm.warp(block.timestamp + 6_674_678); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); - vm.roll(block.number + 48_756); - vm.warp(block.timestamp + 10_087_875); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(69); - vm.roll(block.number + 38_102); - vm.warp(block.timestamp + 15_788_002); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, 100 - ); - vm.roll(block.number + 5750); - vm.warp(block.timestamp + 2503); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false - ); - vm.roll(block.number + 21_989); - vm.warp(block.timestamp + 4_979_832); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true - ); - vm.roll(block.number + 50_175); - vm.warp(block.timestamp + 2_618_050); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership(880, 100); - vm.roll(block.number + 44_581); - vm.warp(block.timestamp + 18_429_750); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_849, 100 - ); // Changed commitment - vm.roll(block.number + 25_967); - vm.warp(block.timestamp + 2_753_174); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(451); - vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11_364_502); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - false - ); - vm.roll(block.number + 11_905); - vm.warp(block.timestamp + 11_497_582); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(20); - vm.roll(block.number + 51_936); - vm.warp(block.timestamp + 11_362_064); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(4_369_999, true); - vm.roll(block.number + 16_748); - vm.warp(block.timestamp + 4_392_799); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 100 - ); - vm.roll(block.number + 34_563); - vm.warp(block.timestamp + 2_767_272); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, - true - ); - vm.roll(block.number + 28_021); - vm.warp(block.timestamp + 24); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 - ); - vm.roll(block.number + 21_122); - vm.warp(block.timestamp + 6_432_758); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, - false - ); - vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6_842_375); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 - ); - } -} diff --git a/test/EchidnaTestRaces.t.sol b/test/EchidnaTestRaces.t.sol index 4c68225..8333268 100644 --- a/test/EchidnaTestRaces.t.sol +++ b/test/EchidnaTestRaces.t.sol @@ -98,36 +98,5 @@ contract EchidnaTestRaces { assert(w.isExpired(focusId) == isExpired); assert(!w.isInGracePeriod(focusId) == (isExpired || isActive)); } - - // Helper for proof verification (if needed in future expansions) - function _verifyMerkleProof( - uint256[20] memory proof, - uint256 root, - uint32 index, - uint256 leaf, - uint8 depth - ) - internal - pure - returns (bool) - { - uint256 current = leaf; - uint32 idx = index; - for (uint8 level = 0; level < depth; level++) { - bool isLeft = (idx & 1) == 0; - uint256 sibling = proof[level]; - uint256[2] memory inputs; - if (isLeft) { - inputs[0] = current; - inputs[1] = sibling; - } else { - inputs[0] = sibling; - inputs[1] = current; - } - current = PoseidonT3.hash(inputs); - idx >>= 1; - } - return current == root; - } } From 010f9da90b25b512228e28072f3d313fd0d089fc Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 7 Nov 2025 10:45:38 +0800 Subject: [PATCH 51/58] fix: remove redundant file --- test/EchidnaReplay.t.sol | 662 --------------------------------------- 1 file changed, 662 deletions(-) delete mode 100644 test/EchidnaReplay.t.sol diff --git a/test/EchidnaReplay.t.sol b/test/EchidnaReplay.t.sol deleted file mode 100644 index 5361628..0000000 --- a/test/EchidnaReplay.t.sol +++ /dev/null @@ -1,662 +0,0 @@ -pragma solidity 0.8.24; - -// Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna -// Assume EchidnaTest.sol is the Echidna harness contract that defines the methods like registerMembership, -// attemptExtensionRace, attemptErasureRace. -import "./EchidnaTest.t.sol"; -import "forge-std/Test.sol"; // Replace with the actual path to EchidnaTest.sol - -contract EchidnaReplay is Test { - EchidnaTest internal echidna; - - function setUp() public { - echidna = new EchidnaTest(); - } - - function test_attemptErasureRace_WakuRLN() public { - vm.roll(block.number + 11_796); - vm.warp(block.timestamp + 5_474_623); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - // Valid Baby Jubjub point x - 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, - // Reduced duration - 100 - ); - vm.roll(block.number + 47_085); - vm.warp(block.timestamp + 9_714_873); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - // Valid Baby Jubjub point y (used as x for variety) - 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, - // Reduced duration - 100 - ); - vm.roll(block.number + 38_103); - vm.warp(block.timestamp + 4_558_906); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - // From signature R x - 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, - // Reduced duration - 100 - ); - vm.roll(block.number + 29_746); - vm.warp(block.timestamp + 13_228_720); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - // From signature R y - 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, - // Reduced duration - 100 - ); - vm.roll(block.number + 58_772); - vm.warp(block.timestamp + 16_726_535); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933 - ); - vm.roll(block.number + 48_493); - vm.warp(block.timestamp + 1_204_344); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_231_738_780_016_212_060_605_121_782_152_175_650_399_916_271_686_623_479_564_981_844_592_372_633_495 - ); - vm.roll(block.number + 36_902); - vm.warp(block.timestamp + 6_674_673); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 14_271_763_308_400_718_165_336_499_097_156_975_241_954_733_520_325_982_997_864_342_600_795_471_836_727 - ); - vm.roll(block.number + 33_845); - vm.warp(block.timestamp + 735_716); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 9_999_044_003_322_463_509_208_400_801_275_356_671_266_978_396_985_433_172_455_084_837_770_460_579_628 - ); - vm.roll(block.number + 35_781); - vm.warp(block.timestamp + 15_419_955); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 14_868_750_298_864_215_918_931_212_669_461_480_940_838_279_805_163_953_554_392_700_481_114_788_988_217 - ); - vm.roll(block.number + 771); - vm.warp(block.timestamp + 17_913_418); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(15_552_001, false); - vm.roll(block.number + 18_055); - vm.warp(block.timestamp + 13_187_508); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 4_498_454_914_711_882_268_466_328_398_075_690_403_183_913_761_650_565_928_933_850_043_231_959_582_090 - ); - vm.roll(block.number + 44_293); - vm.warp(block.timestamp + 11_359_790); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(8_816_298_471_565_553_478_253); - vm.roll(block.number + 53_425); - vm.warp(block.timestamp + 4_444_562); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 745_203_718_271_072_817_124_702_263_707_270_113_474_103_371_777_640_557_877_379_939_715_613_501_666 - ); - vm.roll(block.number + 33_562); - vm.warp(block.timestamp + 14_219_475); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 106_881_024_749_878_243_321_292_280_200_974_139_959_817_939_173_788_106_633_056_826_054_874_002_347_673, - false - ); - vm.roll(block.number + 51_795); - vm.warp(block.timestamp + 16_733_054); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 810_181_532_076_738_148_308_457_416_289_197_585_577_119_693_706_380_535_394_811_298_325_092_337_779, true - ); - vm.roll(block.number + 52_386); - vm.warp(block.timestamp + 13_340_960); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 39_191_598_377_141_549_315_856_730_925_567_207_940_583_071_046_522_612_928_475_157_163_375_553_445_883, - false - ); - vm.roll(block.number + 28_778); - vm.warp(block.timestamp + 19_485_372); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 422_974_903_473_869_924_285_294_686_399_247_660_575_841_594_104_291_551_918_957_116_218_939_002_862 - ); - vm.roll(block.number + 53_838); - vm.warp(block.timestamp + 1); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, 100 - ); - vm.roll(block.number + 46_636); - vm.warp(block.timestamp + 11_821_678); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, 100 - ); - vm.roll(block.number + 57_888); - vm.warp(block.timestamp + 11_470_172); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, 100 - ); - vm.roll(block.number + 53_678); - vm.warp(block.timestamp + 1_059_409); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, 100 - ); - vm.roll(block.number + 9163); - vm.warp(block.timestamp + 5_088_962); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, 100 - ); - vm.roll(block.number + 57_370); - vm.warp(block.timestamp + 7_211_971); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 100 - ); - vm.roll(block.number + 52_325); - vm.warp(block.timestamp + 7_269_956); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, 100 - ); - vm.roll(block.number + 13); - vm.warp(block.timestamp + 11_809_403); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, 100 - ); - vm.roll(block.number + 50_167); - vm.warp(block.timestamp + 10_228_636); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 907_529_701_442_527_636_822_361_196_151_011_186_835_477_052_160_076_110_045_266_796_422_655_750 - ); - vm.roll(block.number + 32_448); - vm.warp(block.timestamp + 6_071_296); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 36_152_006_575_898_071_413_738_485_534_610_504_772_123_181_747_755_834_736_036_287_698_777_015_184_002, - false - ); - vm.roll(block.number + 6729); - vm.warp(block.timestamp + 5_889_939); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 58_463_562_426_656_549_831_725_639_173_426_781_888_371_207_839_773_191_116_779_676_742_569_157_617_676, true - ); - vm.roll(block.number + 49_403); - vm.warp(block.timestamp + 14_818_957); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932 - ); - vm.roll(block.number + 44_385); - vm.warp(block.timestamp + 7_821_507); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 111_185_342_898_521_325_588_224_305_609_230_586_551_748_536_155_220_651_814_001_626_697_158_870_944_491, - false - ); - vm.roll(block.number + 8138); - vm.warp(block.timestamp + 3_986_838); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 5_563_317_320_536_360_357_019_805_881_367_133_322_562_055_054_443_943_486_481_491_020_841_431_450_882, true - ); - vm.roll(block.number + 55_495); - vm.warp(block.timestamp + 13_298_744); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 82_150_570_835_311_748_779_613_601_590_930_899_007_637_956_995_391_819_623_786_983_419_155_333_240_346, - false - ); - vm.roll(block.number + 53_808); - vm.warp(block.timestamp + 16_113_649); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 94_756_843_913_980_367_703_825_440_635_606_010_870_107_150_061_183_736_341_168_934_719_085_836_060_272 - ); - vm.roll(block.number + 53_575); - vm.warp(block.timestamp + 6_685_351); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 22_524_513_599_250_775_770_561_496_810_744_347_426_238_296_396_541_115_644_891_258_189_615_473_070_435, - false - ); - vm.roll(block.number + 35_363); - vm.warp(block.timestamp + 5_418_157); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 89_833_576_623_011_348_753_034_902_489_203_339_405_860_111_267_468_969_771_441_095_409_308_430_642_032, 61 - ); - vm.roll(block.number + 2914); - vm.warp(block.timestamp + 7_963_431); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 2_555_752_030_748_925_341_265_856_133_642_532_487_884_589_978_209_403_118_872_788_051_695_546_807_405, 20 - ); - vm.roll(block.number + 42_147); - vm.warp(block.timestamp + 11_043_183); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 114_754_453_626_733_198_273_777_522_719_098_112_979_869_218_458_062_538_485_135_739_426_192_996_542_208, 36 - ); - vm.roll(block.number + 4708); - vm.warp(block.timestamp + 11_691_783); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 104_896_750_968_454_172_725_482_821_202_386_350_664_629_961_052_485_242_745_091_802_526_249_639_802_019 - ); - vm.roll(block.number + 59_035); - vm.warp(block.timestamp + 11_364_443); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 46_890_934_969_458_242_237_056_668_330_086_728_522_184_233_411_179_055_912_131_707_524_887_240_413_667, 64 - ); - vm.roll(block.number + 59_751); - vm.warp(block.timestamp + 6_021_229); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 108_620_199_967_090_723_474_583_461_904_654_274_942_825_586_337_549_804_002_848_520_230_944_291_922_140, - true - ); - } - - function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59_109); - vm.warp(block.timestamp + 12_682_314); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, - true - ); - vm.roll(block.number + 35_655); - vm.warp(block.timestamp + 15_576_565); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, 100 - ); - vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6_585_509); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, - false - ); - vm.roll(block.number + 24_311); - vm.warp(block.timestamp + 12_762_680); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 100); - vm.roll(block.number + 12_819); - vm.warp(block.timestamp + 1_649_692); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 - ); - vm.roll(block.number + 45_108); - vm.warp(block.timestamp + 1_956_666); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_998_355_040_318_813_176_485_525_989_237_675_206_797_591_310_842_198_122_085_618_117_253_610_484_417, 100 - ); // Changed commitment - vm.roll(block.number + 53_007); - vm.warp(block.timestamp + 276_592); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(834); - vm.roll(block.number + 25_848); - vm.warp(block.timestamp + 11_362_065); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 17_286_222_306_748_121_286_213_072_224_111_296_043_148_465_520_025_078_192_122_982_708_843_485_620_218, 100 - ); // Changed commitment - vm.roll(block.number + 33_171); - vm.warp(block.timestamp + 383_675); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 - ); - vm.roll(block.number + 15_676); - vm.warp(block.timestamp + 11_735_351); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 - ); - vm.roll(block.number + 44_384); - vm.warp(block.timestamp + 18_346_179); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, 100 - ); - vm.roll(block.number + 16_801); - vm.warp(block.timestamp + 573_740); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_848, 100 - ); - vm.roll(block.number + 35_654); - vm.warp(block.timestamp + 4_068_035); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 - ); - vm.roll(block.number + 30_101); - vm.warp(block.timestamp + 4_745_968); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); - vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14_763_861); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 - ); - vm.roll(block.number + 52_780); - vm.warp(block.timestamp + 16_427_024); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, 100 - ); - vm.roll(block.number + 36_392); - vm.warp(block.timestamp + 11_470_167); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true - ); - vm.roll(block.number + 13_355); - vm.warp(block.timestamp + 16_427_025); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false - ); - vm.roll(block.number + 22_867); - vm.warp(block.timestamp + 159_999); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 - ); - vm.roll(block.number + 22_820); - vm.warp(block.timestamp + 4_779_059); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, 100 - ); - vm.roll(block.number + 35_266); - vm.warp(block.timestamp + 3_182_076); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 - ); - vm.roll(block.number + 19_490); - vm.warp(block.timestamp + 299_200); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 - ); - vm.roll(block.number + 51_788); - vm.warp(block.timestamp + 18_651_487); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, - true - ); - vm.roll(block.number + 49_348); - vm.warp(block.timestamp + 12_337_026); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, 100 - ); - vm.roll(block.number + 49_829); - vm.warp(block.timestamp + 12_713_084); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 - ); - vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14_763_856); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(828, true); - vm.roll(block.number + 36_651); - vm.warp(block.timestamp + 4_476_578); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, - false - ); - vm.roll(block.number + 41_972); - vm.warp(block.timestamp + 15_765_194); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true - ); - vm.roll(block.number + 12_338); - vm.warp(block.timestamp + 16_542_398); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 14_931_788_920_454_064_001_300_263_071_209_926_622_155_838_516_781_070_271_701_382_859_038_411_909_782, 100 - ); // Changed commitment - vm.roll(block.number + 21_241); - vm.warp(block.timestamp + 1_018_641); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 12_087_805_090_466_257_955_035_297_089_319_786_504_492_879_194_074_715_547_026_259_420_414_817_602_020, 100 - ); // Changed commitment - vm.roll(block.number + 19_489); - vm.warp(block.timestamp + 2_368_987); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 - ); - vm.roll(block.number + 50_607); - vm.warp(block.timestamp + 6_275_598); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 - ); - vm.roll(block.number + 32_528); - vm.warp(block.timestamp + 11_364_405); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 10_214_781_770_912_242_833_804_544_458_045_074_578_052_133_279_441_312_139_903_402_222_217_539_981_379, 100 - ); // Changed commitment - vm.roll(block.number + 34_897); - vm.warp(block.timestamp + 7_243_908); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, - false - ); - vm.roll(block.number + 32_012); - vm.warp(block.timestamp + 4_454_946); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 - ); - vm.roll(block.number + 28_697); - vm.warp(block.timestamp + 15_970_432); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 20_926_361_652_116_949_211_917_910_507_769_891_523_515_114_854_237_984_902_573_398_155_005_471_856_390, 100 - ); // Changed commitment - vm.roll(block.number + 14_898); - vm.warp(block.timestamp + 4_838_522); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, - false - ); - vm.roll(block.number + 19_847); - vm.warp(block.timestamp + 14_942_829); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, - false - ); - vm.roll(block.number + 12_155); - vm.warp(block.timestamp + 14_219_479); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 - ); - vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287_808); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - true - ); - vm.roll(block.number + 34_448); - vm.warp(block.timestamp + 7_211_969); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, - false - ); - vm.roll(block.number + 16_001); - vm.warp(block.timestamp + 18_874_761); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, - true - ); - vm.roll(block.number + 37_485); - vm.warp(block.timestamp + 11_975_371); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 - ); - vm.roll(block.number + 52_321); - vm.warp(block.timestamp + 18_466_804); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace(477, false); - vm.roll(block.number + 31_665); - vm.warp(block.timestamp + 373_007); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 16_879_454_825_081_464_587_162_311_862_201_197_592_918_867_697_827_323_024_893_827_533_308_814_744_699, 100 - ); // Changed commitment - vm.roll(block.number + 45_111); - vm.warp(block.timestamp + 15_500_872); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 - ); - vm.roll(block.number + 36_506); - vm.warp(block.timestamp + 7_414_210); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership(161, 100); - vm.roll(block.number + 56_897); - vm.warp(block.timestamp + 12_441_897); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, - false - ); - vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16_471_434); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 - ); - vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1_922_225); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 - ); - vm.roll(block.number + 15_232); - vm.warp(block.timestamp + 6_674_678); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); - vm.roll(block.number + 48_756); - vm.warp(block.timestamp + 10_087_875); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(69); - vm.roll(block.number + 38_102); - vm.warp(block.timestamp + 15_788_002); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, 100 - ); - vm.roll(block.number + 5750); - vm.warp(block.timestamp + 2503); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false - ); - vm.roll(block.number + 21_989); - vm.warp(block.timestamp + 4_979_832); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true - ); - vm.roll(block.number + 50_175); - vm.warp(block.timestamp + 2_618_050); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership(880, 100); - vm.roll(block.number + 44_581); - vm.warp(block.timestamp + 18_429_750); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_849, 100 - ); // Changed commitment - vm.roll(block.number + 25_967); - vm.warp(block.timestamp + 2_753_174); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(451); - vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11_364_502); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - false - ); - vm.roll(block.number + 11_905); - vm.warp(block.timestamp + 11_497_582); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(20); - vm.roll(block.number + 51_936); - vm.warp(block.timestamp + 11_362_064); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(4_369_999, true); - vm.roll(block.number + 16_748); - vm.warp(block.timestamp + 4_392_799); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 100 - ); - vm.roll(block.number + 34_563); - vm.warp(block.timestamp + 2_767_272); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, - true - ); - vm.roll(block.number + 28_021); - vm.warp(block.timestamp + 24); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 - ); - vm.roll(block.number + 21_122); - vm.warp(block.timestamp + 6_432_758); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, - false - ); - vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6_842_375); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 - ); - } -} From d37817123c8124ccc70be89393418dcb4b72ccec Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 7 Nov 2025 11:18:01 +0800 Subject: [PATCH 52/58] fix: formatting --- test/WakuRlnV2.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index a951253..6b82a39 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -992,7 +992,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(100); vm.warp(graceStart + gracePeriodDuration + 1); // Expire one @@ -1027,7 +1027,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment1); vm.warp(graceStart); uint256[] memory toErase = new uint256[](1); @@ -1089,7 +1089,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = wZeroGrace.memberships(idCommitment); // Warp just after active period @@ -1128,7 +1128,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment); vm.warp(graceStart + gracePeriodDuration + 1); // Expire From 4de1b76db6de7af8c6db778ff8c3fb9718b67a8f Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 7 Nov 2025 11:21:31 +0800 Subject: [PATCH 53/58] fix: formatting --- test/WakuRlnV2.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 6b82a39..73732f1 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -992,7 +992,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(100); vm.warp(graceStart + gracePeriodDuration + 1); // Expire one @@ -1027,7 +1027,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment1); vm.warp(graceStart); uint256[] memory toErase = new uint256[](1); @@ -1089,7 +1089,7 @@ contract WakuRlnV2Test is Test { , // rateLimit , // index , // holder - // token + // token ) = wZeroGrace.memberships(idCommitment); // Warp just after active period @@ -1128,7 +1128,7 @@ contract WakuRlnV2Test is Test { uint32 gracePeriodDuration,, // rateLimit , // index , // holder - // token + // token ) = w.memberships(idCommitment); vm.warp(graceStart + gracePeriodDuration + 1); // Expire From 657c91756e927ed9e62e0a21212a04797b2264e3 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 7 Nov 2025 11:34:55 +0800 Subject: [PATCH 54/58] fix: adorno + archive EchidnaReplayRaces.t.sol --- .gas-snapshot | 100 ++++++++---------- ....sol => EchidnaReplayRaces.t.sol.archived} | 0 2 files changed, 46 insertions(+), 54 deletions(-) rename test/{EchidnaReplayRaces.t.sol => EchidnaReplayRaces.t.sol.archived} (100%) diff --git a/.gas-snapshot b/.gas-snapshot index 67c15aa..328bb8c 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,41 +1,33 @@ -TestStableTokenTest:test__CannotAddAlreadyMinterRole() (gas: 46264) -TestStableTokenTest:test__CannotMintExceedingMaxSupply() (gas: 26180) -TestStableTokenTest:test__CannotMintWithETHExceedingMaxSupply() (gas: 31142) -TestStableTokenTest:test__CannotMintWithZeroETH() (gas: 18260) -TestStableTokenTest:test__CannotRemoveNonMinterRole() (gas: 22680) -TestStableTokenTest:test__CannotSetMaxSupplyBelowTotalSupply() (gas: 71137) -TestStableTokenTest:test__CheckMinterRoleMapping() (gas: 70674) -TestStableTokenTest:test__ContractDoesNotHoldETHAfterMint() (gas: 110678) -TestStableTokenTest:test__ERC20BasicFunctionality() (gas: 146284) -TestStableTokenTest:test__ETHBurnedEventEmitted() (gas: 112562) -TestStableTokenTest:test__ETHIsBurnedToZeroAddress() (gas: 110523) -TestStableTokenTest:test__InitializeZeroReverts() (gas: 2549161) -TestStableTokenTest:test__MaxSupplyIsSetCorrectly() (gas: 15387) -TestStableTokenTest:test__MintRequiresETH() (gas: 18298) -TestStableTokenTest:test__MintWithDifferentETHAmounts() (gas: 209650) -TestStableTokenTest:test__MinterAddedEventEmitted() (gas: 44969) -TestStableTokenTest:test__MinterRemovedEventEmitted() (gas: 34680) -TestStableTokenTest:test__MinterRoleCanMint() (gas: 98049) -TestStableTokenTest:test__MultipleMinterRolesCanMint() (gas: 128712) -TestStableTokenTest:test__NonMinterNonOwnerAccountCannotMint() (gas: 22487) -TestStableTokenTest:test__NonOwnerCannotAddMinterRole() (gas: 18283) -TestStableTokenTest:test__NonOwnerCannotRemoveMinterRole() (gas: 45753) -TestStableTokenTest:test__NonOwnerCannotSetMaxSupply() (gas: 18048) -TestStableTokenTest:test__OwnerCanAddMinterRole() (gas: 47314) -TestStableTokenTest:test__OwnerCanMintWithoutMinterRole() (gas: 74339) -TestStableTokenTest:test__OwnerCanRemoveMinterRole() (gas: 36526) -TestStableTokenTest:test__OwnerCanSetMaxSupply() (gas: 30706) -TestStableTokenTest:test__RemovedMinterRoleCannotMint() (gas: 37104) -WakuRlnV2Test:testFuzz_Erasure(bool,uint8) (runs: 1000, μ: 984656, ~: 982425) -WakuRlnV2Test:testFuzz_GetMerkleProof(uint32) (runs: 1002, μ: 4104507, ~: 3989323) -WakuRlnV2Test:testFuzz_GetRateCommitmentsRange(uint32,uint32) (runs: 1002, μ: 3669568, ~: 3667740) -WakuRlnV2Test:testFuzz_InvalidExtension(uint256,address,uint256) (runs: 1000, μ: 316358, ~: 316689) -WakuRlnV2Test:testFuzz_MerkleErasures(uint8,bool) (runs: 1001, μ: 3676081, ~: 2201167) -WakuRlnV2Test:testFuzz_MerkleInserts(uint8) (runs: 1001, μ: 3817908, ~: 2690272) -WakuRlnV2Test:testFuzz_MultipleRegisters(uint8) (runs: 1002, μ: 6076714, ~: 3291327) -WakuRlnV2Test:testFuzz_RegisterInvalid(uint256,uint32) (runs: 1000, μ: 60856, ~: 61711) -WakuRlnV2Test:testFuzz_SetActiveDuration(uint32,bool) (runs: 1000, μ: 299053, ~: 312991) -WakuRlnV2Test:testFuzz_SetMaxTotalRateLimit(uint32,bool) (runs: 1000, μ: 420447, ~: 313914) +TestStableTokenTest:test__CannotAddAlreadyMinterRole() (gas: 46248) +TestStableTokenTest:test__CannotMintExceedingMaxSupply() (gas: 26253) +TestStableTokenTest:test__CannotMintWithETHExceedingMaxSupply() (gas: 31196) +TestStableTokenTest:test__CannotMintWithZeroETH() (gas: 18269) +TestStableTokenTest:test__CannotRemoveNonMinterRole() (gas: 22686) +TestStableTokenTest:test__CannotSetMaxSupplyBelowTotalSupply() (gas: 71121) +TestStableTokenTest:test__CheckMinterRoleMapping() (gas: 70476) +TestStableTokenTest:test__ContractDoesNotHoldETHAfterMint() (gas: 110659) +TestStableTokenTest:test__ERC20BasicFunctionality() (gas: 146438) +TestStableTokenTest:test__ETHBurnedEventEmitted() (gas: 112577) +TestStableTokenTest:test__ETHIsBurnedToZeroAddress() (gas: 110526) +TestStableTokenTest:test__InitializeZeroReverts() (gas: 2558591) +TestStableTokenTest:test__MaxSupplyIsSetCorrectly() (gas: 15454) +TestStableTokenTest:test__MintRequiresETH() (gas: 18285) +TestStableTokenTest:test__MintWithDifferentETHAmounts() (gas: 209788) +TestStableTokenTest:test__MintWithETH_RevertsBelowOneETH() (gas: 25455) +TestStableTokenTest:test__MintWithETH_SucceedsAtOneETH() (gas: 110063) +TestStableTokenTest:test__MinterAddedEventEmitted() (gas: 44947) +TestStableTokenTest:test__MinterRemovedEventEmitted() (gas: 34662) +TestStableTokenTest:test__MinterRoleCanMint() (gas: 98092) +TestStableTokenTest:test__MultipleMinterRolesCanMint() (gas: 128755) +TestStableTokenTest:test__NonMinterNonOwnerAccountCannotMint() (gas: 22493) +TestStableTokenTest:test__NonOwnerCannotAddMinterRole() (gas: 18223) +TestStableTokenTest:test__NonOwnerCannotRemoveMinterRole() (gas: 45737) +TestStableTokenTest:test__NonOwnerCannotSetMaxSupply() (gas: 18054) +TestStableTokenTest:test__OwnerCanAddMinterRole() (gas: 47248) +TestStableTokenTest:test__OwnerCanMintWithoutMinterRole() (gas: 74382) +TestStableTokenTest:test__OwnerCanRemoveMinterRole() (gas: 36473) +TestStableTokenTest:test__OwnerCanSetMaxSupply() (gas: 30795) +TestStableTokenTest:test__RemovedMinterRoleCannotMint() (gas: 37073) WakuRlnV2Test:test__EmptyRangePagination() (gas: 307693) WakuRlnV2Test:test__ErasingNonExistentMembership() (gas: 46131) WakuRlnV2Test:test__FullCleanUpErasure() (gas: 1016790) @@ -51,31 +43,31 @@ WakuRlnV2Test:test__InvalidRegistration__InvalidIdCommitment__Zero() (gas: 42830 WakuRlnV2Test:test__InvalidRegistration__InvalidMembershipRateLimit__MinMax() (gas: 55598) WakuRlnV2Test:test__InvalidTokenAmount(uint256,uint32) (runs: 1000, μ: 191620, ~: 191620) WakuRlnV2Test:test__LargePaginationQuery() (gas: 237941853) -WakuRlnV2Test:test__LinearPriceCalculation(uint32) (runs: 1002, μ: 26069, ~: 26069) +WakuRlnV2Test:test__LinearPriceCalculation(uint32) (runs: 1000, μ: 26069, ~: 26069) WakuRlnV2Test:test__MassRegistrationAndErasure() (gas: 2714587) WakuRlnV2Test:test__MaxTotalRateLimitEdgeCases() (gas: 21832122) WakuRlnV2Test:test__MerkleTreeUpdateAfterErasureAndReuse() (gas: 2426716) -WakuRlnV2Test:test__NonMinterCanMintWithETHAndRegister() (gas: 373178) +WakuRlnV2Test:test__NonMinterCanMintWithETHAndRegister() (gas: 373332) WakuRlnV2Test:test__OwnerConfigurationUpdates() (gas: 53177) -WakuRlnV2Test:test__PriceCalculatorReconfiguration() (gas: 669789) +WakuRlnV2Test:test__PriceCalculatorReconfiguration() (gas: 669854) WakuRlnV2Test:test__RegistrationWhenMaxRateLimitIsReached() (gas: 595140) WakuRlnV2Test:test__ReinitializationProtection() (gas: 80197) -WakuRlnV2Test:test__RemoveAllExpiredMemberships(uint32) (runs: 1001, μ: 5076387, ~: 2445573) -WakuRlnV2Test:test__RemoveExpiredMemberships(uint32) (runs: 1001, μ: 1146896, ~: 1146896) -WakuRlnV2Test:test__TokenTransferFailures() (gas: 4126462) +WakuRlnV2Test:test__RemoveAllExpiredMemberships(uint32) (runs: 1000, μ: 4516570, ~: 2259520) +WakuRlnV2Test:test__RemoveExpiredMemberships(uint32) (runs: 1000, μ: 1055797, ~: 1055798) +WakuRlnV2Test:test__TokenTransferFailures() (gas: 4139092) WakuRlnV2Test:test__UnauthorizedMerkleTreeModifications() (gas: 1113852) WakuRlnV2Test:test__Upgrade() (gas: 6702671) WakuRlnV2Test:test__UpgradeWithInvalidImplementation() (gas: 51496) -WakuRlnV2Test:test__ValidPaginationQuery(uint32) (runs: 1001, μ: 386547, ~: 134452) +WakuRlnV2Test:test__ValidPaginationQuery(uint32) (runs: 1000, μ: 378536, ~: 134452) WakuRlnV2Test:test__ValidPaginationQuery__OneElement() (gas: 301276) -WakuRlnV2Test:test__ValidRegistration(uint32) (runs: 1001, μ: 307585, ~: 307585) -WakuRlnV2Test:test__ValidRegistrationExpiry(uint32) (runs: 1001, μ: 288640, ~: 288640) -WakuRlnV2Test:test__ValidRegistrationExtend(uint32) (runs: 1001, μ: 534996, ~: 534996) -WakuRlnV2Test:test__ValidRegistrationExtendSingleMembership(uint32) (runs: 1001, μ: 296279, ~: 296279) -WakuRlnV2Test:test__ValidRegistrationNoGracePeriod(uint32) (runs: 1001, μ: 292251, ~: 292251) -WakuRlnV2Test:test__ValidRegistrationWithEraseList() (gas: 1303567) +WakuRlnV2Test:test__ValidRegistration(uint32) (runs: 1000, μ: 307650, ~: 307650) +WakuRlnV2Test:test__ValidRegistrationExpiry(uint32) (runs: 1000, μ: 288640, ~: 288640) +WakuRlnV2Test:test__ValidRegistrationExtend(uint32) (runs: 1000, μ: 534996, ~: 534996) +WakuRlnV2Test:test__ValidRegistrationExtendSingleMembership(uint32) (runs: 1000, μ: 296279, ~: 296279) +WakuRlnV2Test:test__ValidRegistrationNoGracePeriod(uint32) (runs: 1000, μ: 292251, ~: 292251) +WakuRlnV2Test:test__ValidRegistrationWithEraseList() (gas: 1337020) WakuRlnV2Test:test__ValidRegistration__kats() (gas: 277614) -WakuRlnV2Test:test__WithdrawToken(uint32) (runs: 1001, μ: 277708, ~: 277708) +WakuRlnV2Test:test__WithdrawToken(uint32) (runs: 1000, μ: 283285, ~: 283286) WakuRlnV2Test:test__ZeroGracePeriodDuration() (gas: 8156320) -WakuRlnV2Test:test__ZeroPriceEdgeCase() (gas: 791578) -WakuRlnV2Test:test__indexReuse_eraseMemberships(uint32) (runs: 1001, μ: 4189422, ~: 1421226) \ No newline at end of file +WakuRlnV2Test:test__ZeroPriceEdgeCase() (gas: 791643) +WakuRlnV2Test:test__indexReuse_eraseMemberships(uint32) (runs: 1000, μ: 4269053, ~: 1835792) \ No newline at end of file diff --git a/test/EchidnaReplayRaces.t.sol b/test/EchidnaReplayRaces.t.sol.archived similarity index 100% rename from test/EchidnaReplayRaces.t.sol rename to test/EchidnaReplayRaces.t.sol.archived From 10b89c6165af19bdb256de39bbc61a5b4b137bd9 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 13 Nov 2025 15:45:12 +0800 Subject: [PATCH 55/58] test: focus on erasures with timestamps --- test/EchidnaTestRaces2.t.sol | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 test/EchidnaTestRaces2.t.sol diff --git a/test/EchidnaTestRaces2.t.sol b/test/EchidnaTestRaces2.t.sol new file mode 100644 index 0000000..a47869e --- /dev/null +++ b/test/EchidnaTestRaces2.t.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import "../src/LinearPriceCalculator.sol"; +import "../src/WakuRlnV2.sol"; +import "./TestStableToken.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +// Echidna invariants and assertions for WakuRlnV2 multi-user timestamp manipulation races +contract EchidnaTestRaces2 { + WakuRlnV2 internal w; + TestStableToken internal token; + address internal tokenOwner = address(this); + + // Storage for multi-user registrations and their timestamps (to check races per user) + mapping(uint256 => uint256) internal registrationTimes; // idCommitment => registration timestamp + uint256[] internal registeredIds; // List of registered IDs for iteration in checks + + // Events for logging timestamps + event GracePeriodStart(uint256 timestamp); + event GracePeriodEnd(uint256 timestamp); + event TimestampBeforeAssertions(uint256 timestamp); + + constructor() { + address tokenImpl = address(new TestStableToken()); + bytes memory tokenInitData = abi.encodeCall(TestStableToken.initialize, (1_000_000_000 * 10 ** 18)); + address tokenProxyAddr = address(new ERC1967Proxy(tokenImpl, tokenInitData)); + token = TestStableToken(tokenProxyAddr); + + LinearPriceCalculator priceCalculator = new LinearPriceCalculator(address(token), 1e18 / 20); // Example + + address impl = address(new WakuRlnV2()); + bytes memory initData = abi.encodeCall( + WakuRlnV2.initialize, (address(priceCalculator), 4_294_967_295, 20, 4_294_967_295, 15_552_000, 2_592_000) + ); + address proxyAddr = address(new ERC1967Proxy(impl, initData)); + w = WakuRlnV2(proxyAddr); + } + + // Function to register a single membership; Echidna can call this multiple times with time advances between + function registerMembership(uint256 idCommitment, uint32 rateLimit) public { + (, uint256 price) = w.priceCalculator().calculate(rateLimit); + token.mint(address(this), price); + token.approve(address(w), price); + w.register(idCommitment, rateLimit, new uint256[](0)); + + // Store registration time and add to list + registrationTimes[idCommitment] = block.timestamp; + registeredIds.push(idCommitment); + } + + // Function to attempt erasure on a random registered membership and assert based on current time + function attemptErasureRace(uint256 index, bool fullErase) public { + if (registeredIds.length == 0) return; // Skip if no registrations yet + + uint256 focusId = registeredIds[index % registeredIds.length]; + uint256 regTime = registrationTimes[focusId]; + uint256 activeEnd = regTime + uint256(w.activeDurationForNewMemberships()); + uint256 graceEnd = activeEnd + uint256(w.gracePeriodDurationForNewMemberships()); + emit GracePeriodStart(activeEnd); + emit GracePeriodEnd(graceEnd); + + bool isActive = (block.timestamp < activeEnd); + bool isExpired = (block.timestamp >= graceEnd); + + uint256[] memory ids = new uint256[](1); + ids[0] = focusId; + + bool success = false; + try w.eraseMemberships(ids, fullErase) { + success = true; + } catch { } + + emit TimestampBeforeAssertions(block.timestamp); + + // Additional assertions: State consistency (checked before success to avoid post-erasure state changes) + assert(w.isExpired(focusId) == isExpired); + assert(!w.isInGracePeriod(focusId) == (isExpired || isActive)); + + // Assertion: Erasure should succeed only if not active (i.e., in grace or expired) + assert(success == !isActive); + } +} + From 28d081092d1fa371e0afac5ddb3cba847bbb5186 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 13 Nov 2025 18:21:20 +0800 Subject: [PATCH 56/58] fix: remove isolated test --- test/EchidnaTestRaces2.t.sol | 84 ------------------------------------ 1 file changed, 84 deletions(-) delete mode 100644 test/EchidnaTestRaces2.t.sol diff --git a/test/EchidnaTestRaces2.t.sol b/test/EchidnaTestRaces2.t.sol deleted file mode 100644 index a47869e..0000000 --- a/test/EchidnaTestRaces2.t.sol +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import "../src/LinearPriceCalculator.sol"; -import "../src/WakuRlnV2.sol"; -import "./TestStableToken.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -// Echidna invariants and assertions for WakuRlnV2 multi-user timestamp manipulation races -contract EchidnaTestRaces2 { - WakuRlnV2 internal w; - TestStableToken internal token; - address internal tokenOwner = address(this); - - // Storage for multi-user registrations and their timestamps (to check races per user) - mapping(uint256 => uint256) internal registrationTimes; // idCommitment => registration timestamp - uint256[] internal registeredIds; // List of registered IDs for iteration in checks - - // Events for logging timestamps - event GracePeriodStart(uint256 timestamp); - event GracePeriodEnd(uint256 timestamp); - event TimestampBeforeAssertions(uint256 timestamp); - - constructor() { - address tokenImpl = address(new TestStableToken()); - bytes memory tokenInitData = abi.encodeCall(TestStableToken.initialize, (1_000_000_000 * 10 ** 18)); - address tokenProxyAddr = address(new ERC1967Proxy(tokenImpl, tokenInitData)); - token = TestStableToken(tokenProxyAddr); - - LinearPriceCalculator priceCalculator = new LinearPriceCalculator(address(token), 1e18 / 20); // Example - - address impl = address(new WakuRlnV2()); - bytes memory initData = abi.encodeCall( - WakuRlnV2.initialize, (address(priceCalculator), 4_294_967_295, 20, 4_294_967_295, 15_552_000, 2_592_000) - ); - address proxyAddr = address(new ERC1967Proxy(impl, initData)); - w = WakuRlnV2(proxyAddr); - } - - // Function to register a single membership; Echidna can call this multiple times with time advances between - function registerMembership(uint256 idCommitment, uint32 rateLimit) public { - (, uint256 price) = w.priceCalculator().calculate(rateLimit); - token.mint(address(this), price); - token.approve(address(w), price); - w.register(idCommitment, rateLimit, new uint256[](0)); - - // Store registration time and add to list - registrationTimes[idCommitment] = block.timestamp; - registeredIds.push(idCommitment); - } - - // Function to attempt erasure on a random registered membership and assert based on current time - function attemptErasureRace(uint256 index, bool fullErase) public { - if (registeredIds.length == 0) return; // Skip if no registrations yet - - uint256 focusId = registeredIds[index % registeredIds.length]; - uint256 regTime = registrationTimes[focusId]; - uint256 activeEnd = regTime + uint256(w.activeDurationForNewMemberships()); - uint256 graceEnd = activeEnd + uint256(w.gracePeriodDurationForNewMemberships()); - emit GracePeriodStart(activeEnd); - emit GracePeriodEnd(graceEnd); - - bool isActive = (block.timestamp < activeEnd); - bool isExpired = (block.timestamp >= graceEnd); - - uint256[] memory ids = new uint256[](1); - ids[0] = focusId; - - bool success = false; - try w.eraseMemberships(ids, fullErase) { - success = true; - } catch { } - - emit TimestampBeforeAssertions(block.timestamp); - - // Additional assertions: State consistency (checked before success to avoid post-erasure state changes) - assert(w.isExpired(focusId) == isExpired); - assert(!w.isInGracePeriod(focusId) == (isExpired || isActive)); - - // Assertion: Erasure should succeed only if not active (i.e., in grace or expired) - assert(success == !isActive); - } -} - From b060b007176d876f9a6f6b3c8b4e4f53ab297350 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 13 Nov 2025 18:29:07 +0800 Subject: [PATCH 57/58] test: Echidna tests for races - add dynamic assertions before operation - untrack erased IDs --- test/EchidnaTestRaces.t.sol | 83 ++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/test/EchidnaTestRaces.t.sol b/test/EchidnaTestRaces.t.sol index 8333268..64192fa 100644 --- a/test/EchidnaTestRaces.t.sol +++ b/test/EchidnaTestRaces.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import "../src/LinearPriceCalculator.sol"; import "../src/WakuRlnV2.sol"; +import "../src/Membership.sol"; // Added import for MembershipUpgradeable import "./TestStableToken.sol"; import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; @@ -12,9 +13,8 @@ contract EchidnaTestRaces { TestStableToken internal token; address internal tokenOwner = address(this); - // Storage for multi-user registrations and their timestamps (to check races per user) - mapping(uint256 => uint256) internal registrationTimes; // idCommitment => registration timestamp - uint256[] internal registeredIds; // List of registered IDs for iteration in checks + // Storage for multi-user registrations (to track registered IDs) + uint256[] internal registeredIds; constructor() { address tokenImpl = address(new TestStableToken()); @@ -38,8 +38,7 @@ contract EchidnaTestRaces { token.approve(address(w), price); w.register(idCommitment, rateLimit, new uint256[](0)); - // Store registration time and add to list - registrationTimes[idCommitment] = block.timestamp; + // Add to list (only if successful; reverts otherwise) registeredIds.push(idCommitment); } @@ -48,13 +47,32 @@ contract EchidnaTestRaces { if (registeredIds.length == 0) return; // Skip if no registrations yet uint256 focusId = registeredIds[index % registeredIds.length]; - uint256 regTime = registrationTimes[focusId]; - uint256 graceStart = regTime + uint256(w.activeDurationForNewMemberships()); - uint256 graceEnd = graceStart + uint256(w.gracePeriodDurationForNewMemberships()); + // Query current membership info from contract to handle updates (e.g., from extensions) + MembershipUpgradeable.MembershipInfo memory info; + ( + info.depositAmount, + info.activeDuration, + info.gracePeriodStartTimestamp, + info.gracePeriodDuration, + info.rateLimit, + info.index, + info.holder, + info.token + ) = w.memberships(focusId); + + // If membership doesn't exist (e.g., erased), skip + if (info.rateLimit == 0) return; + + uint256 graceStart = info.gracePeriodStartTimestamp; + uint256 graceEnd = graceStart + uint256(info.gracePeriodDuration); bool isInGrace = (block.timestamp >= graceStart && block.timestamp < graceEnd); bool isExpired = (block.timestamp >= graceEnd); + // Additional assertions: State consistency (pre-operation) + assert(w.isInGracePeriod(focusId) == isInGrace); + assert(w.isExpired(focusId) == isExpired); + uint256[] memory ids = new uint256[](1); ids[0] = focusId; @@ -63,12 +81,8 @@ contract EchidnaTestRaces { success = true; } catch { } - // Assertion: Extension should succeed only if in grace period + // Assertion: Extension should succeed only if in grace period (and sender is holder, but always true here) assert(success == isInGrace); - - // Additional assertions: State consistency - assert(w.isInGracePeriod(focusId) == isInGrace); - assert(w.isExpired(focusId) == isExpired); } // Function to attempt erasure on a random registered membership and assert based on current time @@ -76,13 +90,34 @@ contract EchidnaTestRaces { if (registeredIds.length == 0) return; // Skip if no registrations yet uint256 focusId = registeredIds[index % registeredIds.length]; - uint256 regTime = registrationTimes[focusId]; - uint256 activeEnd = regTime + uint256(w.activeDurationForNewMemberships()); - uint256 graceEnd = activeEnd + uint256(w.gracePeriodDurationForNewMemberships()); + + // Query current membership info from contract to handle updates + MembershipUpgradeable.MembershipInfo memory info; + ( + info.depositAmount, + info.activeDuration, + info.gracePeriodStartTimestamp, + info.gracePeriodDuration, + info.rateLimit, + info.index, + info.holder, + info.token + ) = w.memberships(focusId); + + // If membership doesn't exist (e.g., already erased), skip + if (info.rateLimit == 0) return; + + uint256 graceStart = info.gracePeriodStartTimestamp; + uint256 activeEnd = graceStart; // graceStart is end of active + uint256 graceEnd = graceStart + uint256(info.gracePeriodDuration); bool isActive = (block.timestamp < activeEnd); bool isExpired = (block.timestamp >= graceEnd); + // Additional assertions: State consistency (pre-operation) + assert(w.isExpired(focusId) == isExpired); + assert(w.isInGracePeriod(focusId) == !(isExpired || isActive)); + uint256[] memory ids = new uint256[](1); ids[0] = focusId; @@ -92,11 +127,19 @@ contract EchidnaTestRaces { } catch { } // Assertion: Erasure should succeed only if not active (i.e., in grace or expired) + // (and for grace, sender == holder, but always true here) assert(success == !isActive); - // Additional assertions: State consistency - assert(w.isExpired(focusId) == isExpired); - assert(!w.isInGracePeriod(focusId) == (isExpired || isActive)); + // If successful erasure, remove from local registeredIds to avoid stale entries + if (success) { + // Find and remove focusId from array (swap with last and pop) + for (uint256 i = 0; i < registeredIds.length; i++) { + if (registeredIds[i] == focusId) { + registeredIds[i] = registeredIds[registeredIds.length - 1]; + registeredIds.pop(); + break; + } + } + } } } - From 0d161f64642f0791ed0b1060d1f61186f7236dda Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 14 Nov 2025 10:37:32 +0800 Subject: [PATCH 58/58] fix: remove unused replay test --- test/EchidnaReplayRaces.t.sol.archived | 662 ------------------------- 1 file changed, 662 deletions(-) delete mode 100644 test/EchidnaReplayRaces.t.sol.archived diff --git a/test/EchidnaReplayRaces.t.sol.archived b/test/EchidnaReplayRaces.t.sol.archived deleted file mode 100644 index 5480ac7..0000000 --- a/test/EchidnaReplayRaces.t.sol.archived +++ /dev/null @@ -1,662 +0,0 @@ -pragma solidity 0.8.24; - -// Initial test replay generated from Echidna log at https://getrecon.xyz/tools/echidna -// Assume EchidnaTestRaces.sol is the Echidna harness contract that defines the methods registerMembership, -// attemptExtensionRace, attemptErasureRace. -import "./EchidnaTestRaces.t.sol"; -import "forge-std/Test.sol"; - -contract EchidnaReplayRaces is Test { - EchidnaTestRaces internal echidna; - - function setUp() public { - echidna = new EchidnaTestRaces(); - } - - function test_attemptErasureRace_WakuRLN() public { - vm.roll(block.number + 11_796); - vm.warp(block.timestamp + 5_474_623); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - // Valid Baby Jubjub point x - 9_232_262_805_086_961_470_140_171_118_068_527_502_773_883_397_953_635_627_654_272_948_280_162_222_460, - // Reduced duration - 100 - ); - vm.roll(block.number + 47_085); - vm.warp(block.timestamp + 9_714_873); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - // Valid Baby Jubjub point y (used as x for variety) - 1_146_454_861_477_987_609_722_193_068_493_335_872_063_213_810_781_901_067_275_896_485_680_154_245_472, - // Reduced duration - 100 - ); - vm.roll(block.number + 38_103); - vm.warp(block.timestamp + 4_558_906); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - // From signature R x - 21_166_949_849_736_108_178_593_290_733_041_673_195_425_050_355_037_214_376_832_942_606_083_908_688_572, - // Reduced duration - 100 - ); - vm.roll(block.number + 29_746); - vm.warp(block.timestamp + 13_228_720); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - // From signature R y - 5_042_557_814_597_858_929_471_199_758_284_795_017_757_988_233_023_087_832_786_942_557_701_125_530_716, - // Reduced duration - 100 - ); - vm.roll(block.number + 58_772); - vm.warp(block.timestamp + 16_726_535); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933 - ); - vm.roll(block.number + 48_493); - vm.warp(block.timestamp + 1_204_344); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_231_738_780_016_212_060_605_121_782_152_175_650_399_916_271_686_623_479_564_981_844_592_372_633_495 - ); - vm.roll(block.number + 36_902); - vm.warp(block.timestamp + 6_674_673); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 14_271_763_308_400_718_165_336_499_097_156_975_241_954_733_520_325_982_997_864_342_600_795_471_836_727 - ); - vm.roll(block.number + 33_845); - vm.warp(block.timestamp + 735_716); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 9_999_044_003_322_463_509_208_400_801_275_356_671_266_978_396_985_433_172_455_084_837_770_460_579_628 - ); - vm.roll(block.number + 35_781); - vm.warp(block.timestamp + 15_419_955); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 14_868_750_298_864_215_918_931_212_669_461_480_940_838_279_805_163_953_554_392_700_481_114_788_988_217 - ); - vm.roll(block.number + 771); - vm.warp(block.timestamp + 17_913_418); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(15_552_001, false); - vm.roll(block.number + 18_055); - vm.warp(block.timestamp + 13_187_508); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 4_498_454_914_711_882_268_466_328_398_075_690_403_183_913_761_650_565_928_933_850_043_231_959_582_090 - ); - vm.roll(block.number + 44_293); - vm.warp(block.timestamp + 11_359_790); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(8_816_298_471_565_553_478_253); - vm.roll(block.number + 53_425); - vm.warp(block.timestamp + 4_444_562); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 745_203_718_271_072_817_124_702_263_707_270_113_474_103_371_777_640_557_877_379_939_715_613_501_666 - ); - vm.roll(block.number + 33_562); - vm.warp(block.timestamp + 14_219_475); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 106_881_024_749_878_243_321_292_280_200_974_139_959_817_939_173_788_106_633_056_826_054_874_002_347_673, - false - ); - vm.roll(block.number + 51_795); - vm.warp(block.timestamp + 16_733_054); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 810_181_532_076_738_148_308_457_416_289_197_585_577_119_693_706_380_535_394_811_298_325_092_337_779, true - ); - vm.roll(block.number + 52_386); - vm.warp(block.timestamp + 13_340_960); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 39_191_598_377_141_549_315_856_730_925_567_207_940_583_071_046_522_612_928_475_157_163_375_553_445_883, - false - ); - vm.roll(block.number + 28_778); - vm.warp(block.timestamp + 19_485_372); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 422_974_903_473_869_924_285_294_686_399_247_660_575_841_594_104_291_551_918_957_116_218_939_002_862 - ); - vm.roll(block.number + 53_838); - vm.warp(block.timestamp + 1); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 93_069_777_957_716_534_626_511_592_676_095_128_883_541_549_173_304_417_502_211_440_887_097_265_352_764, 100 - ); - vm.roll(block.number + 46_636); - vm.warp(block.timestamp + 11_821_678); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 51_522_906_060_057_278_679_990_947_101_404_412_153_472_957_736_268_514_263_884_637_927_398_269_578_188, 100 - ); - vm.roll(block.number + 57_888); - vm.warp(block.timestamp + 11_470_172); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 61_542_542_599_287_154_647_970_081_191_182_610_995_985_456_890_733_246_815_310_689_354_155_913_446_715, 100 - ); - vm.roll(block.number + 53_678); - vm.warp(block.timestamp + 1_059_409); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 15_151_206_851_768_761_922_626_779_419_716_885_032_550_609_243_972_739_304_354_508_404_025_123_978_483, 100 - ); - vm.roll(block.number + 9163); - vm.warp(block.timestamp + 5_088_962); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 14_081_762_237_856_300_239_452_543_304_351_251_708_585_712_948_734_528_663_957_353_575_674_639_038_360, 100 - ); - vm.roll(block.number + 57_370); - vm.warp(block.timestamp + 7_211_971); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 108_963_296_912_626_303_058_593_673_031_410_359_103_080_213_800_576_845_606_511_577_526_451_809_781_764, 100 - ); - vm.roll(block.number + 52_325); - vm.warp(block.timestamp + 7_269_956); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 59_854_361_444_067_331_214_800_449_562_275_531_518_062_284_755_304_292_849_816_766_824_186_269_102_025, 100 - ); - vm.roll(block.number + 13); - vm.warp(block.timestamp + 11_809_403); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 30_515_202_238_888_354_901_379_804_575_700_505_769_761_565_567_680_891_590_302_236_564_961_093_984_633, 100 - ); - vm.roll(block.number + 50_167); - vm.warp(block.timestamp + 10_228_636); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 907_529_701_442_527_636_822_361_196_151_011_186_835_477_052_160_076_110_045_266_796_422_655_750 - ); - vm.roll(block.number + 32_448); - vm.warp(block.timestamp + 6_071_296); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 36_152_006_575_898_071_413_738_485_534_610_504_772_123_181_747_755_834_736_036_287_698_777_015_184_002, - false - ); - vm.roll(block.number + 6729); - vm.warp(block.timestamp + 5_889_939); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 58_463_562_426_656_549_831_725_639_173_426_781_888_371_207_839_773_191_116_779_676_742_569_157_617_676, true - ); - vm.roll(block.number + 49_403); - vm.warp(block.timestamp + 14_818_957); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932 - ); - vm.roll(block.number + 44_385); - vm.warp(block.timestamp + 7_821_507); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 111_185_342_898_521_325_588_224_305_609_230_586_551_748_536_155_220_651_814_001_626_697_158_870_944_491, - false - ); - vm.roll(block.number + 8138); - vm.warp(block.timestamp + 3_986_838); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 5_563_317_320_536_360_357_019_805_881_367_133_322_562_055_054_443_943_486_481_491_020_841_431_450_882, true - ); - vm.roll(block.number + 55_495); - vm.warp(block.timestamp + 13_298_744); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 82_150_570_835_311_748_779_613_601_590_930_899_007_637_956_995_391_819_623_786_983_419_155_333_240_346, - false - ); - vm.roll(block.number + 53_808); - vm.warp(block.timestamp + 16_113_649); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 94_756_843_913_980_367_703_825_440_635_606_010_870_107_150_061_183_736_341_168_934_719_085_836_060_272 - ); - vm.roll(block.number + 53_575); - vm.warp(block.timestamp + 6_685_351); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 22_524_513_599_250_775_770_561_496_810_744_347_426_238_296_396_541_115_644_891_258_189_615_473_070_435, - false - ); - vm.roll(block.number + 35_363); - vm.warp(block.timestamp + 5_418_157); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 89_833_576_623_011_348_753_034_902_489_203_339_405_860_111_267_468_969_771_441_095_409_308_430_642_032, 61 - ); - vm.roll(block.number + 2914); - vm.warp(block.timestamp + 7_963_431); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 2_555_752_030_748_925_341_265_856_133_642_532_487_884_589_978_209_403_118_872_788_051_695_546_807_405, 20 - ); - vm.roll(block.number + 42_147); - vm.warp(block.timestamp + 11_043_183); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 114_754_453_626_733_198_273_777_522_719_098_112_979_869_218_458_062_538_485_135_739_426_192_996_542_208, 36 - ); - vm.roll(block.number + 4708); - vm.warp(block.timestamp + 11_691_783); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 104_896_750_968_454_172_725_482_821_202_386_350_664_629_961_052_485_242_745_091_802_526_249_639_802_019 - ); - vm.roll(block.number + 59_035); - vm.warp(block.timestamp + 11_364_443); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 46_890_934_969_458_242_237_056_668_330_086_728_522_184_233_411_179_055_912_131_707_524_887_240_413_667, 64 - ); - vm.roll(block.number + 59_751); - vm.warp(block.timestamp + 6_021_229); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 108_620_199_967_090_723_474_583_461_904_654_274_942_825_586_337_549_804_002_848_520_230_944_291_922_140, - true - ); - } - - function test_attemptExtensionRace_WakuRLN() public { - vm.roll(block.number + 59_109); - vm.warp(block.timestamp + 12_682_314); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 115_710_044_366_489_380_560_145_754_182_836_127_776_606_905_958_965_281_515_627_230_965_944_185_828_197, - true - ); - vm.roll(block.number + 35_655); - vm.warp(block.timestamp + 15_576_565); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_439_145_154_143_552_525_910_919_713_868_996_066_330_922_688_700_283_373_718_845_930_110_014_852_748, 100 - ); - vm.roll(block.number + 5763); - vm.warp(block.timestamp + 6_585_509); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 17_390_757_134_860_691_103_601_339_956_017_953_267_743_470_484_370_144_179_061_550_943_820_859_938_352, - false - ); - vm.roll(block.number + 24_311); - vm.warp(block.timestamp + 12_762_680); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership(30_550_828_421_328_047_254_873_089_071_721_340, 100); - vm.roll(block.number + 12_819); - vm.warp(block.timestamp + 1_649_692); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 104_850_126_800_538_479_521_627_521_813_512_576_589_921_885_869_622_125_078_501_950_362_797_396_775_732 - ); - vm.roll(block.number + 45_108); - vm.warp(block.timestamp + 1_956_666); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 12_998_355_040_318_813_176_485_525_989_237_675_206_797_591_310_842_198_122_085_618_117_253_610_484_417, 100 - ); // Changed commitment - vm.roll(block.number + 53_007); - vm.warp(block.timestamp + 276_592); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(834); - vm.roll(block.number + 25_848); - vm.warp(block.timestamp + 11_362_065); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 17_286_222_306_748_121_286_213_072_224_111_296_043_148_465_520_025_078_192_122_982_708_843_485_620_218, 100 - ); // Changed commitment - vm.roll(block.number + 33_171); - vm.warp(block.timestamp + 383_675); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 7_022_159_125_197_495_734_384_997_711_896_547_675_021_391_130_223_237_843_255_817_587_255_104_160_363 - ); - vm.roll(block.number + 15_676); - vm.warp(block.timestamp + 11_735_351); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 101_185_480_181_713_116_242_457_669_701_483_883_593_620_024_991_591_651_269_453_671_853_652_437_478_102 - ); - vm.roll(block.number + 44_384); - vm.warp(block.timestamp + 18_346_179); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 4_908_416_131_442_887_573_991_189_028_182_614_782_884_545_304_889_259_793_974_797_565_686_968_097_292, 100 - ); - vm.roll(block.number + 16_801); - vm.warp(block.timestamp + 573_740); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_848, 100 - ); - vm.roll(block.number + 35_654); - vm.warp(block.timestamp + 4_068_035); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 18_978_082_967_849_498_068_717_608_127_246_258_727_629_855_559_346_799_025_101_476_822_814_831_852_169 - ); - vm.roll(block.number + 30_101); - vm.warp(block.timestamp + 4_745_968); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace(6_106_105_733_994_696_914_590_284_712_692); - vm.roll(block.number + 6700); - vm.warp(block.timestamp + 14_763_861); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 104_237_522_040_539_086_529_385_814_200_395_911_913_667_236_478_153_241_258_910_237_150_016_100_933_281 - ); - vm.roll(block.number + 52_780); - vm.warp(block.timestamp + 16_427_024); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 8_555_773_188_090_352_132_903_209_190_922_658_630_799_967_488_207_010_664_039_959_647_283_030_053_950, 100 - ); - vm.roll(block.number + 36_392); - vm.warp(block.timestamp + 11_470_167); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_394_776_414_966_240_069_580_838_672_673_694_685_292_165_040_808_226_440_647_796_406_499_139_370_962, true - ); - vm.roll(block.number + 13_355); - vm.warp(block.timestamp + 16_427_025); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 9_630_707_582_521_938_235_113_899_367_442_877_106_957_117_302_212_260_601_089_037_887_382_200_262_601, false - ); - vm.roll(block.number + 22_867); - vm.warp(block.timestamp + 159_999); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 28_243_736_643_972_833_793_366_231_626_843_204_992_644_487_197_555_289_924_254_482_104_591_589_940_922 - ); - vm.roll(block.number + 22_820); - vm.warp(block.timestamp + 4_779_059); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 19_201_590_924_623_513_311_141_753_466_125_212_569_043_677_014_481_753_075_022_686_585_593_991_810_749, 100 - ); - vm.roll(block.number + 35_266); - vm.warp(block.timestamp + 3_182_076); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 43_827_548_018_134_037_042_906_582_304_483_527_074_537_881_763_084_930_140_765_111_011_615_661_349_666 - ); - vm.roll(block.number + 19_490); - vm.warp(block.timestamp + 299_200); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 12_776_298_811_140_222_029_408_960_445_729_157_525_018_582_422_120_161_448_937_390_282_915_768_616_624 - ); - vm.roll(block.number + 51_788); - vm.warp(block.timestamp + 18_651_487); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 107_301_127_263_897_597_227_628_761_122_806_603_306_606_929_334_009_477_725_205_515_511_615_612_118_148, - true - ); - vm.roll(block.number + 49_348); - vm.warp(block.timestamp + 12_337_026); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 14_744_269_619_966_411_208_579_211_824_598_458_697_587_494_354_926_760_081_771_325_075_741_142_829_158, 100 - ); - vm.roll(block.number + 49_829); - vm.warp(block.timestamp + 12_713_084); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 43_792_367_251_478_649_051_155_053_078_982_380_795_888_842_184_379_994_324_460_592_762_045_082_390_946 - ); - vm.roll(block.number + 7659); - vm.warp(block.timestamp + 14_763_856); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(828, true); - vm.roll(block.number + 36_651); - vm.warp(block.timestamp + 4_476_578); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_046_885_519_045_122_606_446_282_744_980_637_739_795_881_293_862_923_481_580_204_068_197_516_138_270, - false - ); - vm.roll(block.number + 41_972); - vm.warp(block.timestamp + 15_765_194); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 7_171_889_270_225_471_948_987_523_104_033_632_910_444_398_328_090_760_036_609_063_776_968_837_717_794, true - ); - vm.roll(block.number + 12_338); - vm.warp(block.timestamp + 16_542_398); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 14_931_788_920_454_064_001_300_263_071_209_926_622_155_838_516_781_070_271_701_382_859_038_411_909_782, 100 - ); // Changed commitment - vm.roll(block.number + 21_241); - vm.warp(block.timestamp + 1_018_641); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership( - 12_087_805_090_466_257_955_035_297_089_319_786_504_492_879_194_074_715_547_026_259_420_414_817_602_020, 100 - ); // Changed commitment - vm.roll(block.number + 19_489); - vm.warp(block.timestamp + 2_368_987); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 4_014_188_762_916_583_598_888_942_667_424_965_430_287_497_824_629_657_219_807_941_460_227_372_577_779, 100 - ); - vm.roll(block.number + 50_607); - vm.warp(block.timestamp + 6_275_598); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 25_686_798_737_320_918_646_636_587_445_932_741_319_837_891_759_549_806_387_798_392_338_795_533_488_010 - ); - vm.roll(block.number + 32_528); - vm.warp(block.timestamp + 11_364_405); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 10_214_781_770_912_242_833_804_544_458_045_074_578_052_133_279_441_312_139_903_402_222_217_539_981_379, 100 - ); // Changed commitment - vm.roll(block.number + 34_897); - vm.warp(block.timestamp + 7_243_908); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 14_593_453_114_436_356_872_569_019_099_482_380_600_010_961_031_449_147_888_385_564_231_161_572_479_533, - false - ); - vm.roll(block.number + 32_012); - vm.warp(block.timestamp + 4_454_946); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 25_925_918_697_093_082_051_988_700_719_536_417_857_215_502_310_699_420_143_298_508_813_462_032_862_395 - ); - vm.roll(block.number + 28_697); - vm.warp(block.timestamp + 15_970_432); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 20_926_361_652_116_949_211_917_910_507_769_891_523_515_114_854_237_984_902_573_398_155_005_471_856_390, 100 - ); // Changed commitment - vm.roll(block.number + 14_898); - vm.warp(block.timestamp + 4_838_522); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_932, - false - ); - vm.roll(block.number + 19_847); - vm.warp(block.timestamp + 14_942_829); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 70_301_009_613_960_490_917_949_744_526_391_086_498_442_689_163_222_427_992_725_693_722_994_258_137_973, - false - ); - vm.roll(block.number + 12_155); - vm.warp(block.timestamp + 14_219_479); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace( - 76_966_217_218_353_830_958_442_135_212_923_621_112_975_360_884_156_253_028_656_115_159_618_856_313_417 - ); - vm.roll(block.number + 9758); - vm.warp(block.timestamp + 287_808); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_933, - true - ); - vm.roll(block.number + 34_448); - vm.warp(block.timestamp + 7_211_969); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_912, - false - ); - vm.roll(block.number + 16_001); - vm.warp(block.timestamp + 18_874_761); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_931, - true - ); - vm.roll(block.number + 37_485); - vm.warp(block.timestamp + 11_975_371); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 37_335_511_784_273_848_537_689_431_468_682_439_708_817_559_909_961_396_759_913_669_152_336_630_041_800 - ); - vm.roll(block.number + 52_321); - vm.warp(block.timestamp + 18_466_804); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptErasureRace(477, false); - vm.roll(block.number + 31_665); - vm.warp(block.timestamp + 373_007); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 16_879_454_825_081_464_587_162_311_862_201_197_592_918_867_697_827_323_024_893_827_533_308_814_744_699, 100 - ); // Changed commitment - vm.roll(block.number + 45_111); - vm.warp(block.timestamp + 15_500_872); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptExtensionRace( - 105_606_550_632_292_314_621_503_518_143_649_535_828_775_273_028_210_522_109_286_717_639_175_153_183_420 - ); - vm.roll(block.number + 36_506); - vm.warp(block.timestamp + 7_414_210); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership(161, 100); - vm.roll(block.number + 56_897); - vm.warp(block.timestamp + 12_441_897); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptErasureRace( - 111_398_094_352_181_033_884_768_016_817_884_715_635_237_389_508_840_493_420_231_528_590_208_237_700_862, - false - ); - vm.roll(block.number + 8898); - vm.warp(block.timestamp + 16_471_434); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 105_337_060_722_689_913_614_253_553_269_990_692_457_515_092_424_074_600_138_749_804_416_711_343_223_382 - ); - vm.roll(block.number + 5723); - vm.warp(block.timestamp + 1_922_225); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 18_872_386_506_188_900_128_178_593_638_530_871_606_212_752_948_544_745_205_989_878_007_158_625_800_496 - ); - vm.roll(block.number + 15_232); - vm.warp(block.timestamp + 6_674_678); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptExtensionRace(4_009_354_985_947_816_657_442_120_275_607); - vm.roll(block.number + 48_756); - vm.warp(block.timestamp + 10_087_875); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(69); - vm.roll(block.number + 38_102); - vm.warp(block.timestamp + 15_788_002); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.registerMembership( - 18_840_924_862_590_752_659_304_250_828_416_640_310_422_888_056_457_367_520_753_407_434_927_494_649_451, 100 - ); - vm.roll(block.number + 5750); - vm.warp(block.timestamp + 2503); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 426_281_677_759_936_592_021_316_809_065_178_817_848_084_678_679_510_574_715_894_138_690_250_139_747, false - ); - vm.roll(block.number + 21_989); - vm.warp(block.timestamp + 4_979_832); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 21_853_424_399_738_097_885_762_888_601_689_700_621_597_911_601_971_608_617_330_124_755_808_946_442_755, true - ); - vm.roll(block.number + 50_175); - vm.warp(block.timestamp + 2_618_050); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.registerMembership(880, 100); - vm.roll(block.number + 44_581); - vm.warp(block.timestamp + 18_429_750); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.registerMembership( - 6_350_874_878_119_819_312_338_956_282_401_532_410_528_162_663_560_392_320_966_563_075_034_087_161_849, 100 - ); // Changed commitment - vm.roll(block.number + 25_967); - vm.warp(block.timestamp + 2_753_174); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(451); - vm.roll(block.number + 9057); - vm.warp(block.timestamp + 11_364_502); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_934, - false - ); - vm.roll(block.number + 11_905); - vm.warp(block.timestamp + 11_497_582); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace(20); - vm.roll(block.number + 51_936); - vm.warp(block.timestamp + 11_362_064); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace(4_369_999, true); - vm.roll(block.number + 16_748); - vm.warp(block.timestamp + 4_392_799); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.registerMembership( - 11_715_857_356_293_458_169_128_266_324_582_842_123_295_933_765_556_118_813_133_626_045_122_493_941_020, 100 - ); - vm.roll(block.number + 34_563); - vm.warp(block.timestamp + 2_767_272); - vm.prank(0x0000000000000000000000000000000000040000); - echidna.attemptErasureRace( - 113_494_438_387_109_549_875_854_423_138_737_438_623_578_968_565_768_162_582_136_905_694_666_899_965_063, - true - ); - vm.roll(block.number + 28_021); - vm.warp(block.timestamp + 24); - vm.prank(0x0000000000000000000000000000000000010000); - echidna.attemptExtensionRace( - 115_369_114_333_842_325_499_285_690_322_288_660_192_694_143_071_536_272_487_538_626_891_694_190_637_069 - ); - vm.roll(block.number + 21_122); - vm.warp(block.timestamp + 6_432_758); - vm.prank(0x0000000000000000000000000000000000030000); - echidna.attemptErasureRace( - 95_725_103_252_022_623_036_343_603_958_987_075_634_200_691_826_026_456_898_605_964_745_085_393_962_918, - false - ); - vm.roll(block.number + 4898); - vm.warp(block.timestamp + 6_842_375); - vm.prank(0x0000000000000000000000000000000000020000); - echidna.attemptExtensionRace( - 24_440_054_405_305_269_366_569_402_256_811_496_959_409_073_762_505_157_381_672_968_839_269_610_695_612 - ); - } -}