ci(abi-gate): cover OutboxDiscovery and bump the asc-contracts pin - #59
ci(abi-gate): cover OutboxDiscovery and bump the asc-contracts pin#59DylanVerstraete wants to merge 1 commit into
Conversation
asc-contracts #38 merged OutboxDiscovery with the automatic timelock. Our ABI drift gate was pinned at main @ 2026-08-17, before the contract existed, so nothing was checking the surface the registry-first resolver is about to read. Mirror IOutboxDiscovery (only what we read) and assert it against the compiled artifact: five events and six reads. A moved topic0 silently blinds a subscription, and the timelock events are the only advance notice we get before a default changes or an Outbox is removed. A moved selector makes a read revert with empty returndata, which the resolver cannot distinguish from "no Outbox for this chain key" - it would resolve to nothing and idle. Captured in the mirror's doc comments because both are easy to get wrong later: effectiveTime is a unix timestamp, not a block number; and activeOutboxes() drops an Outbox the moment its scheduled removal time passes, so membership disappearing is NOT the signal to stop watching one. Deliberately not asserting activeOutboxCount: it existed in the reviewed revision of #38 and was dropped before merge. The pre-existing outboxOf assertion stays: OutboxDeployer.outboxOf still exists at a4d05d7, so the bump is clean there too. Verified by running the gate in strict mode against a fresh hardhat compile of a4d05d7. Claude-Session: https://claude.ai/code/session_01Kv6y52MHgtgkWmnJhdXbHB
PR SummaryLow Risk Overview Adds Extends Reviewed by Cursor Bugbot for commit ac4450c. Bugbot is set up for automated code reviews on this repo. Configure here. |
Relayer twin of creditcoin3 #1316. asc-contracts #38 merged OutboxDiscovery with the automatic timelock (
a4d05d7); our ABI drift gate was pinned ate300c166, main @ 2026-08-17 — before the contract existed.What this adds
IOutboxDiscoverymirrored inwrite-ability(only the surface we read), asserted against the compiled artifact:Events (5) —
OutboxRegistered,OutboxRemovalScheduled,DefaultOutboxChangeScheduled,PendingDefaultCancelled,PendingRemovalCancelledReads (6) —
defaultOutbox(uint32),activeOutboxes(uint32),isActiveOutbox,defaultDeployer(),pendingDefaultOutbox,pendingRemovalTimeA moved topic0 silently blinds a subscription, and the timelock events are our only advance notice before a default changes or an Outbox is removed. A moved selector makes a read revert with empty returndata, which the registry-first resolver cannot distinguish from "no Outbox for this chain key" — it would resolve to nothing and idle.
Notes captured in doc comments
effectiveTimeis a unix timestamp, not a block number. Our listeners are block-indexed, so there is a conversion to write.activeOutboxes()filters an Outbox out the moment its scheduled removal time passes, beforecleanupruns. Membership disappearing is not the signal to stop watching one — we drain on our own in-flight state.Deliberately not asserted
activeOutboxCount— present in the revision of #38 I reviewed, dropped before merge.Pre-existing assertion unaffected
OutboxDeployer.outboxOf(uint32)still exists ata4d05d7, so the existingRegistryResolverassertion passes on the new pin. Separately (not this PR):outboxOfis a per-deployer mapping, and the confirmed cross-generation truth isOutboxDiscovery.defaultOutbox— that is the resolver rescope for #50, which this mirror now makes possible.Verification
Gate run in strict mode (
ABI_GATE_STRICT=1) against a freshnpx hardhat compileofa4d05d7: passes.cargo test --workspace171 pass / 0 fail, clippy-D warningsclean, fmt clean,ci.ymlparses, pinned SHA verified to resolve to the #38 merge commit onmain.https://claude.ai/code/session_01Kv6y52MHgtgkWmnJhdXbHB