From ed0fb1dc7a881c05d1adbe55ad997416085ffd1f Mon Sep 17 00:00:00 2001 From: Josh Hardy Date: Mon, 10 Aug 2026 15:37:47 +0000 Subject: [PATCH] docs(lib): correct which guard term rejects a leaked cancelled pending node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adversarial-pass finding (libs C2) on LibCorporateActionsPause. The pending branch guard `pendingCursor != NODE_NONE && pendingEffective != 0` attributed the rejection of a leaked cancelled node (effectiveTime == 0) to the `!= 0` term, but that term is logically dead here: the inner `pendingEffective > block.timestamp` re-assertion already rejects a zero (or past) effectiveTime, since `0 > block.timestamp` is false. Deleting the `!= 0` conjunct is a provably equivalent mutant — no test can distinguish the two programs. Corrected the comment to state that the `> block.timestamp` re-assertion is what closes the phantom-node hole on this branch, and that the `!= 0` twin IS load-bearing on the COMPLETED branch (where the re-assertion is `<= block.timestamp`, which 0 satisfies). Comment-only; no behaviour change. 191 tests; fmt/slither clean. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_013hi8wq9YkjWPcGACXCEKeL --- src/lib/LibCorporateActionsPause.sol | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib/LibCorporateActionsPause.sol b/src/lib/LibCorporateActionsPause.sol index 6d833d5..1f7e51d 100644 --- a/src/lib/LibCorporateActionsPause.sol +++ b/src/lib/LibCorporateActionsPause.sol @@ -77,9 +77,17 @@ library LibCorporateActionsPause { // from `ICorporateActionsV1` — cursor `0` is a real bootstrap node and // must NOT be treated as "no match". // `effectiveTime == 0` is the documented sentinel for a cancelled - // (unlinked) node; under the upstream unlinking contract such a node - // is never returned by the traversal API, but we reject it here as - // defence-in-depth so a leaked cancelled node cannot yield `(true, 0)`. + // (unlinked) node; under the upstream unlinking contract such a node is + // never returned by the traversal API. On THIS (pending) branch the + // `pendingEffective != 0` conjunct is belt-and-suspenders that is + // actually SUBSUMED by the `pendingEffective > block.timestamp` + // re-assertion below: `0 > block.timestamp` is false, so a leaked + // cancelled node is rejected by that check regardless. The conjunct is + // kept for symmetry and self-documentation, but note it is the + // `> block.timestamp` re-assertion — not the `!= 0` term — that closes + // the phantom-node hole here. (On the COMPLETED branch the `!= 0` twin + // IS load-bearing, because there the re-assertion is `<= block.timestamp`, + // which `0` satisfies.) if (pendingCursor != NODE_NONE && pendingEffective != 0) { // Defence-in-depth: re-assert the PENDING filter's invariant // locally. `pendingEffective > now` is guaranteed server-side by