POST FIAT

Post Fiat · pfUSDC on Arc · technical review packet

One USDC, there and back, authorized by proofs of the two chains’ own finality.

On 2 September 2026 we deposited 1.000000 USDC into a vault on Arc testnet, proved Arc's own validator quorum finalized it inside a zero-knowledge proof, minted pfUSDC on the PostFiat L1 against that proof, burned it, proved PostFiat finality of the burn under ML-DSA signatures, and released the USDC on Arc against that proof. This page pins every hop to its hash.

Date 2026-09-02 UTC
Arc testnet, chain 5042002
PFTL postfiat-wan-devnet-2, 6 validators
Source postfiatorg/postfiatl1v2 #37

The story, in plain English: what this is for

What is a NAVCoin. A NAVCoin is a new financial primitive: a token whose value tracks the machine-verified net asset value of a real portfolio, the way a fund share tracks a fund, rather than a peg to a dollar. It lets someone turn USDC into exposure to a portfolio and back again, privately, and without trusting an issuer's quarterly PDF, because the backing, the valuation, and the redemption claim are checked by code and tied to the token's supply. It is built to ride the surge in on-chain stocks, commodities, and other tokenized real-world assets: as those assets move on-chain, portfolios of them can be held, swapped, and redeemed the same way. The design is public in the NAVCoin proposal and the private swap explainer.

Who is asking, and for what. Post Fiat runs its own blockchain, where people and AI agents hold and trade NAVCoins. When someone buys into a NAVCoin they pay in dollars, and when they cash out they get dollars back. Those dollars are USDC, and the copy of that USDC that lives on Post Fiat's chain is called pfUSDC. Every pfUSDC is backed one-for-one by real USDC locked in a vault contract on another blockchain, so the pfUSDC vault is the dollar leg of every NAVCoin subscription and redemption. Post Fiat is applying to Circle's Arc Ecosystem Program for $250,000 in four milestone-locked payments, and is proposing that the security firm Zellic join as co-applicant and independent auditor. Zellic has not yet agreed to this; this page is the material we are putting in front of them to decide. The money pays for independent security audits and for running the proof-generating machines as a reliable service; Post Fiat pays for the engineering itself. This page exists because the proposal promised that every claim would be backed by running software, and this is that software, running.

Why Circle would want this. Arc is Circle's own blockchain, and transaction fees on it are paid in USDC. What Circle needs from early builders is real usage rather than farmed activity, and integrations that show what Arc was built for. Post Fiat's offer is to move its USDC vault onto Arc. After that, every time anyone buys into or cashes out of a NAVCoin, real USDC moves into or out of a vault on Arc, with the fee paid in USDC. That is recurring settlement volume tied to asset management, not a one-off demo. The proposal starts with a $500,000 reserve on Arc once the audit clears, a path to moving most of Post Fiat's reserves there, and a public demonstration of an AI agent doing paid work and being paid in USDC on Arc.

Why the zero-knowledge part matters to Arc. A bridge is the software that lets USDC locked on one chain be represented on another. Almost every bridge relies on a small trusted group, a committee or multisig, to say "yes, that deposit happened," and that trusted group is where most of the billions in bridge hacks came from. This bridge is designed to have no such group, and none was involved in the transactions on this page. One caveat, stated in §04: on this test deployment a single administrative key could still bypass the withdrawal check, and removing it is the first job of the audit. Going in, a zero-knowledge proof, a compact piece of math anyone can check, shows that Arc's own validators confirmed the deposit. Going out, a contract on Arc checks a proof that Post Fiat's validators confirmed the withdrawal. That gives Circle two things to talk about: Arc's confirmations can be verified by other chains with math rather than trust, and Post Fiat's validators sign with post-quantum signatures, the kind designed to survive quantum computers, verified inside a proof on Arc. Several of Arc's founding validators are banks and payment networks with active quantum-risk programs; this is a concrete answer for them.

Why a co-application with Zellic would make sense. A demonstration on a test network is a demo. The same system, audited by an independent security firm and then run with a capped amount of real money, is a product Circle can point to. The proposed split is simple: Post Fiat brings the working software, the auditor brings the review that makes it something institutions can rely on, and the grant's audit tranches pay for that review. If Zellic takes this on, the rest of this page is the evidence they would start from rather than a pitch: every step tied to a transaction you can look up, 32 deliberately tampered inputs correctly rejected, and the one known weakness stated up front rather than buried (§04). Closing that weakness before real money is at stake is exactly what the audit money is for.

Status of this document. Prepared as the basis for a proposed co-application with Zellic, who have not yet reviewed or agreed to anything. Nothing here has been audited, reviewed, endorsed, or co-sponsored by Zellic or Circle. Arc testnet is alpha software operated by Circle; the PostFiat devnet is a controlled six-validator network. Amounts are testnet USDC. One open finding qualifies the egress claim on this deployment: the SP1 gateway owner key (EOA 0xdB9b78C8…3814) can admit an unproven withdrawal by registering a permissive verifier under a new selector, because the finality verifier does not pin the proof selector. It is stated in full in §04, reproduced by a forge test, and its fix is the first item in the audit scope.
Deposited on Arc
1,000,000atoms · 1.000000 USDC
Minted, burned, released
1,000,000atoms, exact each way
Corrupted witnesses rejected
12 + 20ingress + egress
Administrative keys
2one is an open egress-soundness finding, §04

01 What was demonstrated

Both directions of the bridge are authorized by succinct proofs of the other chain's finality, verified on-chain. Ingress verifies Arc's Ed25519 commit certificate over the exact block that carries the deposit receipt, plus an EIP-1186 proof of Arc's validator registry at that exact block so the signing set is proven, not assumed. Egress verifies PostFiat's ML-DSA (FIPS-204) consensus certificates inside an SP1 zkVM, wrapped to a constant-size Groth16 proof that an Arc contract checks. There is no attestation layer and no operator checkpoint write. The design intends no signer fallback either; on this testnet deployment that intent is not yet met on egress, because the SP1 gateway owner key can route around the Groth16 check (§04). The transactions below were all authorized by real proofs; the finding is about what the gateway owner could do, and it is what we want audited first.

Everything below ran on real infrastructure on 2 September 2026: a live Arc testnet deposit, an operator-run Arc node for the registry proofs, an A100 for proving, and the six-validator PostFiat devnet with the Arc-capable release deployed through a six-clone deployment gate earlier the same day. Every transaction and contract on this page links to the Arc explorer; every artifact links to the evidence file committed on the branch.

02 The round trip, hop by hop

Arc testnet · block 60,163,641

Deposit 1.000000 USDC into the vault status 1

The depositor calls depositV2 on the immutable vault. The vault pulls exactly 1,000,000 atoms, derives the canonical deposit id, records it in the direct-mode ingress anchor, and emits the deposit log the proof will open.

tx
0xbc8a1b3875394e0132e99a5815a6a66107afa8b894cd6370440a6fbdd1c7259c
block hash
0x89671619436737312c15007d6a83b51d628da356af2de1f37e4229c789d5b11d
vault
0x160307f3EfeAd79B6A3629c4b8D90E8301fC250F
deposit id
0xfe5f47725604a0112574fac5a0726bd83bb26cdd250d0315f561de21dc5e7e60
depositor
0x0995876e5A97C036C0fDa8846F8F47B57B6d2BFc
recipient
pffcb93d9f87a843a8aa34e1adf241f5d58143e81b (PostFiat)

evidence · ingress/deposit.receipt.json · ingress/deposit.env

Operator-run Arc node · exact block

Capture the witness: certificate, receipt, and registry proofs native verify pass

From our own Arc v0.8.0 execution + consensus follower (public Arc RPCs do not serve historical eth_getProof; four were probed and all declined), the capture tool pulled the commit certificate for the block, the receipt trie proof, and EIP-1186 account and storage proofs for the validator-registry proxy and its implementation at exactly that block: 2 + 5N storage slots for N = 20 registered validators. The guest re-derives the validator set from proven storage, requires ≥ ⅔ voting power on the certificate, and binds the deposit log byte-for-byte.

validators
20 registered · 19 signatures on the certificate
set commitment
75d2bed78b313f681ad0976e67a486032cc83582b414e04d51ff04d51cc0a2fa (in = out, no rotation; matches the governance-pinned Arc finality state on PostFiat)
registry proxy
0x3600000000000000000000000000000000000002 · code hash pinned in guest
witness
witness.v2.json · 1.9 MB · captured seconds after the deposit
  • Forged signaturerejectedARC_INGRESS_INVALID_SIGNATURE
  • Sub-quorum signing powerrejectedARC_INGRESS_SUB_QUORUM
  • Mutated receiptrejectedARC_INGRESS_RECEIPT_PROOF
  • Wrong deposit log fieldsrejectedARC_INGRESS_DEPOSIT_MISMATCH
  • Stale validator-set commitmentrejectedARC_INGRESS_VALIDATOR_SET_COMMITMENT_MISMATCH
  • Wrong registry account proofrejectedARC_INGRESS_ROTATION_ACCOUNT_PROOF
  • Wrong registry storage proofrejectedARC_INGRESS_ROTATION_STORAGE_PROOF
  • Wrong storage slotrejectedARC_INGRESS_ROTATION_STORAGE_LAYOUT
  • Reordered validator setrejectedARC_INGRESS_ROTATION_STORAGE_LAYOUT
  • Zero-power validator keptrejectedARC_INGRESS_ROTATION_STORAGE_LAYOUT
  • Duplicate validatorrejectedARC_INGRESS_ROTATION_STORAGE_LAYOUT
  • Rotation without proofrejectedARC_INGRESS_ROTATION_PROOF_UNAVAILABLE

evidence · ingress/witness.v2.json · ingress/capture.log · ingress/negative-suite.v2.json · ingress/audit.log

Prover · NVIDIA A100 80 GB · SP1 v6.1.0

Prove Arc finality + receipt inclusion (Groth16) verified locally

The witness is executed by the pfusdc-arc-ingress guest and wrapped to Groth16. The program identity is the one rebuilt independently in CI earlier today from two clean source trees, byte-identical to the checked-in ELF.

program vkey
0x0050a8b0daed2fa75f44d4102b42204c34668a03d311cb727cc6ca3f8df5cf16
proof
356 bytes calldata · 314 bytes public values · BN254, 15,972,262 constraints
groth16 wrap
19.3 s on GPU (wall 11.8 min including a one-time 8 GB circuit download)

evidence · ingress/proof/proof-report.json · execute-report.json · proof-calldata.bin · public-values.bin · CI rebuild run 33586405990

PostFiat devnet · blocks 943 – 947

Admit the proof and mint 1,000,000 pfUSDC 6/6 converged

Governance first bound pfUSDC to the Arc verifier: the Arc proof profile was registered (943), the NAV asset re-registered onto it (944), and the epoch-9 route profile with its Arc finality bootstrap activated by a six-validator signed batch (945). The relay bundle carried the Groth16 proof and public values; the PostFiat node's bounded verifier checked it against the pinned vkey and the governance-pinned Arc finality state, then propose (946) and finalize + claim (947) executed as certified rounds.

route
pfusdc-arc-testnet-tier4-epoch9 · profile hash f7ce6d3cce3bd058a218db6bd829b01be13c576a2270aed362052d12654fc7a911a8423ee2d961ca45dbf72c08df6ae2 · binding 0xd9e0cd409c5d1e118d65c78ee059adcbba937616353e9675e350d52ee8d498b2
supply
303,700,595 → 304,700,595 atoms issued (Δ = +1,000,000 exactly)
recipient
pffcb93d9f87a843a8aa34e1adf241f5d58143e81b balance 0 → 1,000,000 in the Arc source-series of pfUSDC
Arc finality state
advanced from block 60,146,559 to 60,163,641, set commitment unchanged

evidence · devnet/arc-profile-register-round.finality.json · relay-bundle.report.json · arc-propose.report.json · arc-finalize-claim.report.json · ingress/route-profile.v2.json

PostFiat devnet · block 948

Burn 1,000,000 pfUSDC to redeem to Arc accepted

The holder burns the full amount with destination evm-erc20:5042002:0x0995876e5a97c036c0fda8846f8f47b57b6d2bfc. Issued supply returns to exactly 303,700,595. The redemption is recorded with its withdrawal packet and EVM digest — the values the egress proof commits to.

redemption
0a998d305f42f229c98e4f461d28af0a63d16f6553ed0fbc63fe245d300581d035ab3140a9df3adc67fbaae8f75e19f9
burn tx
65d00f38a8caf6ca423c9fca63494882fdbe77ea77077efb224fe4b30cc2da04b2095b522f11f2506d775cc975638819
packet digest
0x4875362412805c49bd332dd2778bb36707fee198125caa6128b28a3532f26d74

evidence · the accepted burn receipt and the withdrawal packet are carried literally inside egress/egress-witness.json

PostFiat devnet · checkpoint 931 → burn block 948

Capture the egress witness from two validators byte-identical

The egress witness carries three things: the 16-block finality ancestry (blocks 932–947) that links the verifier's pinned checkpoint at height 931 to the burn block; the burn block 948 itself with its consensus-v2 commit certificate (committee epoch 3, ML-DSA-65 signatures from the six-validator committee, quorum 5); and the burn receipt with its Merkle path plus the withdrawal packet. Captured independently on validators 0 and 3; identical bytes (sha256 e4d5202be88f8411671c9a97228f7f307aa3b2078f96a0806bab673c6fd5975a).

  • Wrong chain id in QC domainrejectedwrong_chain · QC schema or domain mismatch
  • Wrong genesis in QC domainrejectedwrong_genesis · QC schema or domain mismatch
  • Ancestry does not start at the checkpointrejectedstale_checkpoint · ancestry is not contiguous
  • Burn predates exit-root activationrejectedwrong_bridge_exit_activation
  • Route profile record substitutedrejectedwrong_route_profile_hash · record hash mismatch
  • Exit root not bound by the commitrejectedwrong_committed_bridge_exit_root · commit does not bind header
  • Proposal without commitrejectedproposal_only · block has no consensus-v2 commit
  • Prepare-phase QC presented as commitrejectedprepare_only · QC vote target mismatch
  • Four of six signers (sub-quorum)rejectedfour_of_six_or_under_quorum · QC committee mismatch
  • Duplicate validator in committeerejectedduplicate_validator · committee inactive / non-ML-DSA / duplicate
  • Committee not derived from ancestryrejectedwrong_committee · committee does not follow proved ancestry
  • Bad ML-DSA signature or contextrejectedbad_mldsa_signature_or_context · signature verification failed
  • Rejected receipt presented as acceptedrejectedrejected_receipt · literal accepted burn receipt absent
  • Receipt status code alteredrejectedwrong_receipt_code · literal accepted burn receipt absent
  • Wrong Merkle pathrejectedwrong_merkle_path · invalid leaf bounds
  • Exit leaf alteredrejectedaltered_exit_leaf · exit proof root mismatch
  • Withdrawal packet alteredrejectedaltered_withdrawal_packet · leaf ≠ packet
  • Recipient swappedrejectedwrong_recipient · leaf ≠ packet
  • Packet hash alteredrejectedwrong_withdrawal_packet_hash · hash/digest mismatch
  • EVM digest alteredrejectedwrong_withdrawal_packet_evm_digest · hash/digest mismatch

evidence · egress/egress-witness.json · egress/egress-negative-suite.json (20 cases, 20 rejected, 0 accepted) · egress/egress-audit.log

Prover · NVIDIA A100 40 GB · SP1 v6.1.0

Prove PostFiat finality of the burn (ML-DSA in-circuit) verified locally

The pfusdc-egress guest verifies every ML-DSA-65 certificate in the ancestry and on the burn block 948, the burn's inclusion, and the withdrawal packet, and commits the recipient, amount, withdrawal and burn commitments, and packet digest as public values.

program vkey
0x0036cbe7d36bbfe1118a3c544eeba74f3791d2a19bf5ec59b972f72d36416852 — the identity pinned immutably in the deployed Arc verifier
guest execution
271,252,755 cycles (post-quantum signature checks dominate) · 8.8 s
proof
356 bytes calldata · 1,486 bytes public values · Groth16 over BN254
time
core proof ≈ 70 s on GPU; 9.2 min wall including the one-time circuit download

evidence · egress/proof/proof-report.json · execute-report.json · proof-calldata.bin · public-values.bin · cuda-prover.log

Arc testnet · block 60,170,160

Release exactly 1,000,000 USDC against the proof status 1 · replay reverts

withdrawWithProof(publicValues, proof): the finality verifier at 0x1D436908516D15E3c55A936899B47a885e047F27 verified the Groth16 proof through the SP1 v6.1.0 gateway, checked the checkpoint lineage from height 931, and consumed the proof nullifier, withdrawal-id and burn-tx commitments; the vault transferred the amount to the recipient encoded in the proof and asserted both balance deltas exactly. Re-submitting the same proof reverts with ProofAlreadyConsumed(nullifier) (selector 0xfab54c75).

tx
0x86036658acab859dc1ab8200140a33ddadfac603ca402fb041e504a28e77a207
vault balance
2,000,000 → 1,000,000 atoms (Δ = −1,000,000 exactly; the remaining 1,000,000 is an earlier unrelated deposit)
recipient
0x0995876e5A97C036C0fDa8846F8F47B57B6d2BFc received 1,000,000 atoms; gas 517,762 paid in USDC
events
ProofNativeWithdrawal (topic 0x8955c89501fd9e0e81ae8abac51a6a5774d6261d19cf3c8cce49cb6fc071f329) on the vault; two verifier events (checkpoint advance, nullifier consumed); two ERC-20 Transfer logs

evidence · egress/withdraw.receipt.json · withdraw.balances.txt · withdraw.replay.txt · withdraw.preflight.txt

03 Contracts and identities under review

ObjectAddress / identityBinding
SP1 v6.1.0 Groth16 verifier0xd3b199D0C643dab3F28E5C97D0067763e28187b2VERIFIER_HASH 0x4388a21c687fdd5f218d7e3d13190cac4c5355818d3605fd5fb811df468ee696; runtime code hash 0xc26a6452cb4fb09bc555e9ba44384da0267da540ec8700a87f8f4801520b2fa1 matches pinned sp1-contracts v6.1.0
Arc-local SP1 gateway0x532D3a8035b87646a92245eCaa01e6602a13654eroute 0x4388a21c → 0xd3b199D0…, not frozen; owner() = 0xdB9b78C87F76054b204188109b35cE4614d03814 (deployer EOA). The finality verifier's immutable sp1Verifier points here. Owner powers and mitigation in §04.
One-shot deployment factory0xC4932b2d2E2E7A97c90c1595a13A5913C70cab81CREATE nonces 1 and 2 predict anchor and vault; no setter, no upgrade path
PFTL finality verifier0x1D436908516D15E3c55A936899B47a885e047F27no owner function; egress vkey 0x0036cbe7d36bbfe1118a3c544eeba74f3791d2a19bf5ec59b972f72d36416852; route epoch 9; checkpoint block id 8e3639ee748255636d09adb8b3fe70f20f8ae0aa9388b024eaffb98b7a94f3c7c4b0e5710f0d8c2479b08d9bc8665c4b (height 931); committee root ca8da61a23bf9d1d1e9ddf57edfe8ee7e26a33ac04c8ff6bee44c3e419083e03b1ecfd3e3299db3f9c6a8b0f5471f6c4
Ingress anchor0x92390D3a2102CB74E4746c05B4d91F61093475D0direct mode; pinned vault; route binding 0xd9e0cd409c5d1e118d65c78ee059adcbba937616353e9675e350d52ee8d498b2
Vault0x160307f3EfeAd79B6A3629c4b8D90E8301fC250Ftoken 0x3600000000000000000000000000000000000000 (Arc USDC); runtime code hash 0x8d15bb9dc20c416db72c724eeeb725b8b395cb850a889cde130645dcc752764e equals the immutable pinned in the verifier; owner() = 0x0995876e5A97C036C0fDa8846F8F47B57B6d2BFc (pause only)
Arc ingress guestvkey 0x0050a8b0daed2fa75f44d4102b42204c34668a03d311cb727cc6ca3f8df5cf16ELF sha256 7660fcc58677cfec433a5f2337b9fe46fa96374a1e3c4bd6fba625b982d881bc; two clean CI rebuilds byte-identical (GitHub Actions run 33586405990)
PFTL egress guestvkey 0x0036cbe7d36bbfe1118a3c544eeba74f3791d2a19bf5ec59b972f72d36416852ELF sha256 8b0f266a035a432ef3c0e4233672d8a15b913cefd4c85ff07f91f008601bb744; same CI rebuild
PFTL releasearc-current-v2-a699d560 (git a699d560a9275ce769d25e5196d819a069a7285b) · binary sha256 7f4288f3b5182933d253c19661fd563d85c5ca94764497d727b37d6f991f9c0bsigned manifest, verified by every validator's unit at start; six-clone gate passed before rollout

04 Trust model, stated plainly

Ingress (Arc → PostFiat)

Trust is Arc's own consensus: a ≥ ⅔ voting-power quorum of the validator set proven from registry storage at the exact block. A two-thirds collusion of that permissioned cohort could fabricate an ingress fact. Nothing else can: no relayer, no RPC provider (a dishonest provider can only withhold), no operator key.

The registry proof is mandatory even when the set does not change; the guest fails closed without it.

Egress (PostFiat → Arc)

Trust is PostFiat consensus soundness (ML-DSA-65 committee certificates, quorum 5 of 6 on this devnet) plus SP1/Groth16 soundness. The Arc verifier holds a checkpoint that advances only by proof.

Replay is excluded twice: the withdrawal-id commitment and the burn-tx commitment are both consumed on first use.

Privileged controls on this testnet deployment, enumerated

Vault setPaused, held by EOA 0x0995876e5A97C036C0fDa8846F8F47B57B6d2BFc. Liveness only: pause halts deposits and withdrawals; it cannot move funds, alter the verifier, or admit a proof.

SP1 gateway owner(), EOA 0xdB9b78C87F76054b204188109b35cE4614d03814. This is the finding we want reviewed first. The gateway's addRoute reverts RouteAlreadyExists for selector 0x4388a21c, so the owner cannot swap the Groth16 verifier behind today's proofs. The owner can, however, (i) freezeRoute(0x4388a21c), which halts egress (liveness), and (ii) register a route for a different selector to any contract exposing VERIFIER_HASH(). Because PFTLFinalityVerifierV1 forwards proofBytes to the gateway without pinning the four-byte selector, a proof prefixed with such a selector bypasses the Groth16 check. On this testnet that key is therefore a soundness assumption on egress, not only a liveness one. Ingress is unaffected: the PostFiat-side verifier is in-node and governance-pinned.

Reproduced, not just asserted. Four tests in PFUSDCTier4.t.sol deploy the unmodified verifier behind a gateway replica with the exact Arc topology and show: the registered 0x4388a21c route cannot be replaced (RouteAlreadyExists); a forged proof under 0x4388a21c is rejected; freezeRoute halts egress; and, the PoC, a route added under selector 0xdeadbeef lets a bare four-byte "proof" release funds. forge test --root crates/ethereum-contracts --match-contract PFUSDCTier4Test --match-test Gateway.

Mitigation, planned and not yet deployed: the finality verifier binds its immutable sp1Verifier directly to the SP1 v6.1.0 Groth16 verifier at 0xd3b199D0… and rejects any proofBytes whose selector is not 0x4388a21c; the gateway leaves the trust base entirely. The contracts here are immutable, so this is a redeploy of the pair (factory → anchor + vault + verifier), which is why it is scheduled with the audit rather than patched in place. Until then the precise statement is: egress soundness = PostFiat consensus + SP1/Groth16 + non-misuse of the gateway owner key.

Deposits use Arc's transparent path because the proof opens the deposit log.

05 Reproduce and review

Everything is open source at github.com/postfiatorg/postfiatl1v2, branch integrate/arc-tier4-current-v2-20260901. Evidence and source links on this page are pinned to commit 1c136a17 so they cannot drift; the evidence directory is docs/evidence/arc-mvp-20260828/devnet-20260902 (49 files). The claim-classification packet maps every statement in the grant proposal to verified / demonstrated / implemented / planned / aspirational, and the audit scope lists the components, threat model, and deliverables we are requesting. Contracts: crates/ethereum-contracts/src. Guests: programs/pfusdc-arc-ingress, programs/pfusdc-egress. Prover and audit tool: tools/pfusdc-tier4-prover.

# conformance against pinned arc-node source (certificates, receipts, negatives)
cargo test -p arc-conformance --locked

# vault, anchor, factory, finality verifier (22 tests, mock SP1 verifier; 4 of them are the §04 gateway PoC)
forge test --root crates/ethereum-contracts --match-contract PFUSDCTier4Test -vv

# re-run both negative suites against today's witnesses
pfusdc-tier4-prover arc-ingress-audit --witness witness.v2.json --output out.json
pfusdc-tier4-prover egress-audit --witness egress-witness.json --output out.json

# verify today's Groth16 proofs against the pinned vkeys
pfusdc-tier4-prover arc-ingress --witness witness.v2.json --output-dir ./x   # executes; --prove to reproduce

What this page does not claim: