Files
precompile/modules
zeekay a26ca0f056 precompile/dex: refuse activation without explicit protocolFeeController
DEX module previously defaulted ProtocolFeeController to Anvil/Foundry
account #0 (0xf39Fd6...92266) whose private key
(0xac0974...80) is in every Foundry user's ~/.foundry. At Quasar Edition
activation, any random caller could have invoked PauseDEX, ResumeDEX,
or the irreversible FreezePool on the chain-wide AMM precompile — a
chain-wide compromise the cryptographer review caught.

Fix is a fail-closed activation gate:

  - dex/module.go::Configure() returns ErrDEXNoProtocolFeeController when
    upgrade.json dexConfig omits protocolFeeController (zero address).
    luxd will refuse to advance past the activation block until the
    operator populates the field with a real KMS-controlled multisig.
  - compromisedDevControllers map blocks all ten Anvil deterministic
    accounts; any explicit attempt to install a public dev key fails with
    ErrDEXCompromisedController (the address is included in the error).
  - dex/dex_test.go covers: zero-address rejection, all 10 anvil
    addresses rejected, a real address activates cleanly, random callers
    cannot invoke admin functions even with a real controller, and the
    Configure interface still returns *Config.

Same audit pass also wires three previously-stub-only precompiles into
the modules.RegisterModule registry so upgrade.json can gate them:

  - kzg4844 (LP-3665 KZG point-evaluation extensions, ConfigKey=kzg4844Config)
  - ed25519 (LP-3211, ConfigKey=ed25519Config) — Solana/TON/XRP signature
    verify lands as a first-class registered precompile alongside the
    legacy NewModule() metadata wrapper.
  - secp256r1 (EIP-7212 P256-verify, ConfigKey=secp256r1Config) — stateful
    adapter wraps the existing Contract.Run(input) into a contract
    StatefulPrecompiledContract that does gas deduction and strict-PQ
    refusal uniformly.
  - modules/registerer.go extends reservedRanges with 0x100-0x1FF
    (post-EVM-standard EIP band, for P256) and 0x32000...0000 to
    0x32FF000...0000 (high-byte LP-3xxx classical-signature page, for
    ed25519). Both ranges are narrow enough that no other precompile
    family overlaps.

router precompile audit: no Anvil default existed there (RouterConfig
already used zero-as-skip semantics rather than zero-as-default).

Tests:
  go test -count=1 -race -timeout 120s ./dex/... ./kzg4844/... \\
    ./ed25519/... ./secp256r1/... ./modules/...
All pass; full ./... suite (49 packages) green.
2026-06-01 21:04:56 -07:00
..