From 83f35ab68e7f277ee527c88f5f2b8bbdd5139e41 Mon Sep 17 00:00:00 2001 From: David Meister Date: Mon, 15 Jun 2026 00:19:54 +0000 Subject: [PATCH] constrain bounded keys not raw fuzz inputs in signed context tests boundPrivateKey is not injective over the full uint256 domain, so two distinct fuzz inputs (e.g. 0 and 1) can fold onto the same private key. The bad-signature assertions in testFlowBasicValidateMultipleSignedContexts and testFlowBasicValidateSignedContexts only hold when alice and bob have distinct keys, but the tests guarded the raw inputs via vm.assume(fuzzedKeyBob != fuzzedKeyAlice). Under the colliding case the 'bad' signature is signed by the same key it claims as signer, so it validates and the expected InvalidSignature revert never fires (deterministic under seed 0xdeadbeef at higher run counts). Move the assume onto the bounded keys (aliceKey != bobKey) so the revert path is exercised across the input domain without the degenerate collision masquerading as a failure. Closes #479 Co-Authored-By: Claude Opus 4.8 --- test/src/concrete/Flow.signedContext.t.sol | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/src/concrete/Flow.signedContext.t.sol b/test/src/concrete/Flow.signedContext.t.sol index 2fb7e6e4..e0bd481b 100644 --- a/test/src/concrete/Flow.signedContext.t.sol +++ b/test/src/concrete/Flow.signedContext.t.sol @@ -22,11 +22,15 @@ contract FlowSignedContextTest is FlowTest { uint256 fuzzedKeyAlice, uint256 fuzzedKeyBob ) public { - vm.assume(fuzzedKeyBob != fuzzedKeyAlice); (IFlowV5 flow, EvaluableV2 memory evaluable) = deployFlow(); uint256 aliceKey = boundPrivateKey(fuzzedKeyAlice); uint256 bobKey = boundPrivateKey(fuzzedKeyBob); + // `boundPrivateKey` is not injective over the full uint256 domain, so + // distinct fuzz inputs can fold onto the same key. The bad-signature + // assertion below only holds when the two keys actually differ, so + // constrain the bounded keys (not the raw inputs). + vm.assume(aliceKey != bobKey); SignedContextV1[] memory signedContexts = new SignedContextV1[](2); @@ -55,11 +59,15 @@ contract FlowSignedContextTest is FlowTest { uint256 fuzzedKeyAlice, uint256 fuzzedKeyBob ) public { - vm.assume(fuzzedKeyBob != fuzzedKeyAlice); (IFlowV5 flow, EvaluableV2 memory evaluable) = deployFlow(); uint256 aliceKey = boundPrivateKey(fuzzedKeyAlice); uint256 bobKey = boundPrivateKey(fuzzedKeyBob); + // `boundPrivateKey` is not injective over the full uint256 domain, so + // distinct fuzz inputs can fold onto the same key. The bad-signature + // assertion below only holds when the two keys actually differ, so + // constrain the bounded keys (not the raw inputs). + vm.assume(aliceKey != bobKey); SignedContextV1[] memory signedContext = new SignedContextV1[](1); signedContext[0] = vm.signContext(aliceKey, aliceKey, context0);