OpenZeppelin / OpenZeppelin/compact-contracts

dev: check @circuitInfo annotations against the compiled k/rows

Open
#750 0 comments 0 reactions 1 assignee View on GitHub

@0xisk is already working on this.

Since Jul 29, 2026.

2-low enhancement
Dominant language
TypeScript
Stars
55
Forks
29
Avg merge
5d 7h
Merged PRs (30d)
25

Description

🧐 Motivation

Every circuit in the repo carries a hand-maintained @circuitInfo k=…, rows=… annotation, and nothing checks it. A refactor that changes a circuit's cost leaves the annotation stale, silently. Reviewers and audit readers treat those numbers as fact, and a k bump is the number that matters most: it doubles proving cost and moves a circuit toward the block and proving limits.

There is no test for this today because the numbers aren't in the artifact. Confirmed by inspection, not assumption:

number compiler/contract-info.json zkir/*.zkir zkir/*.bzkir keys/*
names, pure, proof, ABI
k only inferable from prover-key size
rows

bzkir headers start midnight:ir-source and prover keys midnight:prover-key[; neither encodes k. Verifier keys are a constant 2119 bytes across every circuit. k can be recovered from prover-key size (size / 2^k lands in 297.9–344.8 against 2× per k step), but that is a constant fitted to a serialization format we don't own.

📝 The data already exists

@openzeppelin/compact-builder already solves the hard part. CompilerService spawns compact under a PTY via script — because compactc only renders the constraint table to a terminal — and Compiler.js parses it and calls writeCircuitInfoJson, producing .circuit-info.json beside the sources:

{
  "generatedAt": "2026-07-27T13:07:56.652Z",
  "files": {
    "MockFungibleToken.compact": [
      { "name": "_approve", "k": 11, "rows": 1409 },
      { "name": "_transfer", "k": 12, "rows": 2192 }
    ]
  }
}

Eight such files exist across contracts/src/** today. So nothing needs to be produced — it needs to be checked.

Two properties of that file shape the design:

  • it is written only on a full compile, since k and rows come from the ZK pass (--skip-zk yields only the Compiling N circuits: header)
  • it is gitignored (.gitignore:28), so it is a build product with no committed baseline

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.