Skip to content

Commit 9c2032c

Browse files
improve cft docs (OpenZeppelin#720)
1 parent 6e4f497 commit 9c2032c

1 file changed

Lines changed: 38 additions & 10 deletions

File tree

contracts/src/token/ConfidentialFungibleToken.compact

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ pragma language_version >= 0.23.0;
7070
* depth), but that counter RESETS on `clearMemos`, so it is an in-epoch
7171
* backstop only, never a substitute for freshness.
7272
*
73+
* Seed generation is a WALLET responsibility and OUT OF SCOPE for this
74+
* contract, which cannot enforce it. The witness shipped in this repo
75+
* (`test/witnesses/ConfidentialFungibleTokenWitnesses.ts`) is TEST-ONLY and
76+
* returns a FIXED seed for reproducibility; it is NOT a production wallet. A
77+
* production integration MUST supply a fresh, high-entropy, secret 32-byte seed
78+
* per invocation from a CSPRNG; there is no production reference witness here, so
79+
* confidentiality is only as strong as that external, not-yet-built wallet layer.
80+
*
7381
* @dev Plaintext disclosures (what reaches the public ledger):
7482
* - This base discloses no amounts; supply accounting lives in a layer.
7583
* - A public-supply layer reveals each mint/burn amount via the totalSupply
@@ -119,6 +127,17 @@ pragma language_version >= 0.23.0;
119127
* calls dominate the credit-path row counts; there is currently no cheaper,
120128
* upgrade-safe hasher available.
121129
*
130+
* @dev Runtime trust boundary. Confidentiality and integrity rest on the
131+
* Midnight runtime enforcing two curve invariants this module does NOT re-check:
132+
* every JubjubPoint reaching a curve op is cofactor-cleared into the prime-order
133+
* subgroup (so off-curve, low-order, or mixed-order points make the circuit
134+
* unsatisfiable), and `ecMul` faults on a scalar >= the subgroup order. These are
135+
* regression-pinned with adversarial inputs in
136+
* `crypto/test/CurveRuntimeInvariants.test.ts`, which fails loudly if a future
137+
* runtime stops enforcing them. That is behavioral verification of the shipped
138+
* runtime, NOT a formal audit of its circuit implementation (`midnight-circuits`),
139+
* which remains an external trust assumption.
140+
*
122141
* @dev Caller-identity gating (composability). This module is unopinionated
123142
* about compliance policy (freeze, KYC, pause); a composing contract layers
124143
* that on top. Gating a circuit on an EXPLICIT argument (e.g. the recipient
@@ -147,18 +166,27 @@ pragma language_version >= 0.23.0;
147166
* conflict. Documented limitation; acceptable for the v1 target use case
148167
* (tokenized deposits).
149168
*
169+
* Domain separation. The memo KDF and per-operation randomness are
170+
* domain-separated by a version tag but NOT bound to a chain id or
171+
* contract-instance identifier, so cross-DEPLOYMENT isolation (the same wallet
172+
* seed reused against two instances or two chains) relies on the seed-freshness
173+
* requirement above rather than on the derivation itself. Binding `kernel.self()`
174+
* into the derivations is a possible defense-in-depth hardening; under review, deferred.
175+
*
150176
* Block weight. A deploy bundles every exported entry point's on-chain IR into
151177
* one transaction, and the value circuits are SHA256-heavy (k=16), so a
152-
* full-surface deployment can exceed the node's per-transaction block byte
153-
* budget and be rejected (`1010: Transaction would exhaust the block limits`).
154-
* The full token surface exceeds it; a reduced surface (e.g. receive +
155-
* transfer, dropping allowances and supply accounting) fits, as measured on the
156-
* local ledger-8 dev stack. The lever is dropping the k=16 value operations a
157-
* deployment does not need, not just trimming getters. The limit is a
158-
* governance-configurable, node-side ledger parameter, so confirm against the
159-
* target network. Keep the deployed circuit surface small (drop
160-
* unused getters, split oversized composites); raising the limit is a
161-
* node-side change which is tracked upstream:
178+
* full-surface deployment is byte-heavy. Whether it fits is a property of the
179+
* target network, not the contract: the per-transaction block byte budget is a
180+
* governance-configurable, node-side ledger parameter. On the local ledger-8 dev
181+
* stack the full surface exceeded it and was rejected (`1010: Transaction would
182+
* exhaust the block limits`), while a reduced surface (e.g. receive + transfer,
183+
* dropping allowances and supply accounting) fit. So confirm deployability
184+
* against the target network; if a deployment is over budget there, the lever is
185+
* exposing only the k=16 value operations it needs, not just trimming getters.
186+
* A deployed contract can also be upgraded by its Contract Maintenance Authority
187+
* (CMA), so an over-budget deployment can start with a lean surface and add
188+
* operations by upgrade instead of fitting the whole surface into one deploy.
189+
* Raising the limit itself is a node-side change, tracked upstream:
162190
* https://github.com/midnightntwrk/midnight-node/issues/1202.
163191
*
164192
* Residual griefing. The dual-balance split (see `sweep`) stops dust

0 commit comments

Comments
 (0)