From 228239b7d9be022275472a7833e5bf248f2d223f Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 7 Oct 2025 15:30:28 +1100 Subject: [PATCH 01/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] test: Echidna contract with invariants - registerMembership - attemptExtensionRace - attemptErasureRace --- test/EchidnaTest.t.sol | 140 +++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 69 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 - - (, 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"); + // Store registration time and add to list + registrationTimes[idCommitment] = block.timestamp; + registeredIds.push(idCommitment); } - // Helper for proof verification + // 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, From f735f68b5b2816f2b01b17612a7d035b4704e2ca Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 27 Oct 2025 13:59:00 +0800 Subject: [PATCH 20/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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"