The registrar digest bound only the selector and the arguments, so a signature
set authorising "register chain 5" stayed valid forever: anyone who saw the
original transaction could re-apply it after an unregister, or re-apply a
superseded SetGateway. The digest now carries a governance nonce that advances
after each successful write. Selector 0x06 reads it. The nonce lives outside
the govSlot namespace so re-seeding cannot revive retired authorisations.
Two more, both reachable without any signature being valid. Every submitted
signature is ECRECOVERed before any of them is known to belong to an operator,
and the flat write fee bought up to 255 of them; signatures are now billed at
the EVM's own ECRECOVER price. And loadGovernance allocated from a count it
read out of storage, which genesis alloc can pre-populate at any address, so a
malformed genesis could ask for four billion addresses at boot.
The bridge package carried a full custodial lock-mint cross-chain bridge
(BridgeGateway: liquidity pools, daily limits, a 2/3 signer set) and an
in-memory MPC attestation layer (BridgeSigner) — neither wired to any
precompile address or Run dispatch, both guarding fund movement with STUB
verifiers (verifySignature / VerifyThresholdSignature returned
len(signature) > 0, accepting any non-empty bytes).
Cross-chain value movement is now the sole responsibility of the HTLC
atomic-swap precompile LP-90A0 (swap/), where every payout is backed by a
real transferFrom-observed lock and released only on a SHA-256 preimage or
timeout — non-custody is structural, not policy. Keeping a second, dormant
custodial path violated 'exactly one way' and left a mint surface that
could later be wired behind a fake verifier.
Removes gateway.go, signer.go, types.go and their tests; bridge/ is now a
pure chain registry (registrar precompile, registry rows — no fund
movement). No reachable code path changes: the deleted machinery was
depended on by nothing outside its own files (verified by build + grep).
go vet + go test -race ./bridge/... green; registry LP-90A0 intact.
A registry-driven gateway constructor lets tests and curated networks
build a gateway whose supported-chain set comes from a Registry rather
than the hard-coded ecosystem defaults. Supports(id) is the obvious
read-side mirror of that set, taken under the gateway's existing RLock.
Pinned by TestGateway_RegistryDriven (bridge/registry_test.go:165) which
was added during the registry refactor but the constructor + method had
not been wired up yet.
The Err var block had no ErrChainNameTooLong but two production sites
(registrar.go:360, registry_state.go:154) and a test case were already
returning it — package failed to compile cleanly across all subdirs.
Added the missing sentinel completes the bridge precompile error set.