Skip to main content

Decision

Every signature verification site uses OpenZeppelin’s SignatureChecker.isValidSignatureNow rather than ECDSA.recover. This transparently supports both EOAs (ecrecover, ~5.6k gas) and smart accounts (ERC-1271 isValidSignature, ~12–15k gas for Safe). Safe is the recommended wallet for nodes and high-value clients. Session keys via ERC-7579 smartsessions handle the hot signing paths (per-MB vouchers, per-probe/stream slash_sig).

What SignatureChecker changes

ECDSA.recover(hash, sig) → address reverses a signature into an address. This doesn’t work for ERC-1271 contracts, which reply “yes/no” given (hash, sig, address). SignatureChecker.isValidSignatureNow(signer, hash, sig):
  • For an EOA address, falls through to ecrecover — same cost, same semantics.
  • For a contract address, calls signer.isValidSignature(hash, sig) — the standard ERC-1271 path.
The verification pattern shifts from recover-then-lookup to verify-against-provided-address. The verifier must already know the claimed signer; it cannot derive it from the signature.

Unchanged

  • EIP-712 domains and typed data hashes — unchanged. Safe’s ERC-1271 implementation validates the same EIP-712 payloads.
  • Voucher format — unchanged. The Voucher carries the signer’s address already; no schema migration.
  • EOA flow — fully supported. Clients and nodes that prefer EOAs stay on EOAs.

Hot path: Safe-7579 + session keys

The hot signing path runs on Safe-7579 + erc7579/smartsessions. Session keys give:
  • ERC-1271 validation (Safe signs)
  • Time windows (expire at X)
  • Selector- and domain-scoped action policies (only sign vouchers for channel Y)
  • Per-session spending caps
  • First-class revocation
Per-MB voucher signing runs against a scoped session key with a bounded lifetime and spending cap — compromise of the session key costs at most the cap and expires quickly.

SlashJudge implications

SlashJudge verifies slash_sig against a provided Ethereum address rather than recovering it. The offender’s address comes from the on-chain NodeId binding in StakingRegistry — the challenger supplies the NodeId, the contract looks up the bound address, and SignatureChecker verifies the signature against that address. Works for both EOA-owned nodes and Safe-owned nodes uniformly. Source ADR: 024-account-abstraction.md