0010. Keep go-ethereum for EIP-712 and secp256k1 signing
- Status: Proposed
- Date: 2026-09-30
Context
The backend signs two kinds of typed data for Polymarket:ClobAuth for L1 auth
(Phase 2) and CLOB orders for the CTF and Neg Risk exchanges, wrapped in the Deposit
Wallet’s ERC-7739 TypedDataSign and the Session Key wrapper (Phase 3,
venue notes §4 and §10).
Phase 2 uses github.com/ethereum/go-ethereum v1.17.6 for this.
The Phase 2 security review (finding P2-10) noted that the go-ethereum surface is large
for what it does. signer/core/apitypes pulls in core/types, kzg4844, params and
more to hash one struct. With CGO off it uses the pure-Go decred secp256k1 code; a
CGO-on Linux build would compile C libraries instead. govulncheck was clean. The review
asked for either a small EIP-712 encoder checked against the golden vectors, or an ADR
accepting go-ethereum. The tech lead chose to keep it (PLAN Phase 3 decisions).
Decision
- Keep go-ethereum for EIP-712 hashing and secp256k1 signing.
-
The packages used are:
Phase 3 adds the order and
TypedDataSignhashing in the same package; whether it usesapitypesorcryptodirectly is defined by implementation. -
All EIP-712 and signing code stays in
venue/polymarket/signing(CLAUDE.md). Other packages import only thecommontypes and, inapp, address derivation. - Byte-for-byte golden vectors from the official SDK stay the acceptance test for every hash and signature, whatever library computes them.
-
From Phase 6, every build runs with
CGO_ENABLED=0: the Docker image,task buildand CI. go-ethereum then always uses its pure-Go secp256k1, and the binary has no C dependencies.
Consequences
- No new cryptographic code to write or review. go-ethereum’s EIP-712 encoder is widely
used and already matches all
ClobAuthvectors. - The dependency tree is large. govulncheck and osv-scanner run on every lint; a finding in go-ethereum is triaged like any other, and most of its packages are never called.
- Binary size and build time are higher than a small encoder would give. Both are acceptable for a single server binary.
- Upgrading go-ethereum is a signing change: it needs the security review and the golden vectors to pass.
Alternatives considered
- A small EIP-712 encoder in
signing(about 200 lines: type string,encodeData, domain separator), withgolang.org/x/crypto/sha3for Keccak anddecred/dcrd/dcrec/secp256k1for signing. Rejected for now. It removes most of the dependency tree but adds hand-written cryptographic encoding, including the nestedTypedDataSigntype, to a path where a bug costs money. The golden vectors would catch errors in the cases they cover, not in the cases they do not. The review can reopen this if go-ethereum causes a vulnerability or build problem. - Only the go-ethereum
cryptopackage, with a hand-written encoder. Rejected for the same reason: the encoder is the part with the most room for error, andcryptoalone is not what makes the dependency large.