test(integration): CFT composition spec suite#696
Draft
0xisk wants to merge 66 commits into
Draft
Conversation
PR #620 moved every unit suite to the async, backend-aware @openzeppelin/compact-simulator@0.2.0 API, but the ElGamal suite added on this branch still used the synchronous createSimulator path. Against 0.2.0 the spec fails to load (TypeError: Cannot read properties of undefined reading 'kind'), which is the only failing suite in the test workflow on #617. * ElGamalSimulator: drop the sync constructor for `static async create`, add `artifactName: 'MockElGamal'`, and return `Promise<R>` from every pure pass-through (the assert circuits return `Promise<[]>`). * ElGamal.test.ts: build the simulator in `beforeAll`, derive the shared keys once, await every circuit call, and assert failure paths with `await expect(...).rejects.toThrow(...)`. No behavioral change to the contract; the migration is mechanical and mirrors the UtilsSimulator / utils.test.ts pattern from #620.
test(crypto): migrate ElGamal suite to async simulator
Rename ConfidentialFungibleTokenCore to ConfidentialFungibleToken: it is the token module consumers import, not an internal shared core (the NST family keeps a Core because two wrappers share it; CFT has one). Mock, simulator, and test files follow the same rename.
Expose the supply-changing halves under their intent names: _mint delegates to _credit, _burn to _debit, _burnFrom to _spendEscrow. They perform no supply accounting; a composing contract pairs them with the supply tracker extension when it wants a tracked totalSupply, and gates them per its issuance policy. Docs updated to frame the module as supply-neutral rather than supply-free.
Standalone public supply tracker mirroring NativeShieldedTokenSupply: an _totalSupply cell with _addSupply/_subSupply building blocks and the totalSupply getter, importing no token module. A consuming contract calls the accounting block alongside the matching token op (_mint, _burn, _burnFrom); the assembled pairing ships as the ConfidentialFungibleTokenPublicSupply preset.
The assembled token (former ConfidentialFungibleTokenPublicSupply module) composes two production pieces, so it leaves src/ and becomes a top-level TEST-ONLY contract under test/integration/_mocks, pairing every supply op with its accounting block: mint = _addSupply + _mint, burn = _burn + _subSupply, burnFrom = _burnFrom + _subSupply. The module's unit mock, simulator, and test suite are removed with it; the composition's integration spec suite follows in a separate PR.
Simulator for the composed ConfidentialFungibleTokenPublicSupply integration contract (driving its artifact directly), plus the shared spec helpers: test users (ALICE/BOB), deployCft, actAs/registerAs, and fundAs (mint + sweep + plaintext-cache for a fresh account).
Per-case specs under specs/confidentialFungibleToken/ (metadata, mint, burn, burnFrom, supplyConservation), following the specs/<topic>/<case>.spec.ts layout. Ports the coverage of the removed unit suite and adds: * supply conservation across transfer, approve/transferFrom, _move, and sweep (only paired mint/burn/burnFrom may move totalSupply) * multi-user end-to-end mint -> transfer -> sweep -> burn flow * escrow burn-down to zero and the exhaustion failure * burnFrom with no escrow * burn pushes no memo (debits are memo-less) * registration and metadata wiring smoke tests
privacy.spec observes only the public ledger: balances, pending, and escrows stay ciphertexts; the approve cap never appears in clear; transfer leaks the counterparty graph (memo growth) but no amount; mint/burn disclose their amounts through the totalSupply delta by design; hostile wallets (wrong EK, overstated plaintext or allowance) fail the witness-binding checks. concurrency.spec documents the same-block limitation from the module header by proving its cause deterministically: with the witness seed pinned, an identical credit replayed on top of a changed recipient pre-state yields a different transcript (so two same-pre-state transactions conflict), credits to distinct recipients touch disjoint cells (no conflict), and sweep contests the same pending cell an incoming credit writes.
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Types of changes
What types of changes does your code introduce to OpenZeppelin Midnight Contracts?
Put an
xin the boxes that applyFixes: N/A. Test suite for the CFT layout proposal (#653 + andrew-fleming#10, tracking #569).
What this adds
The integration spec suite for the composed
ConfidentialFungibleTokenPublicSupplycontract (test/integration/_mocks/), closing the coverage gap that andrew-fleming#10 deliberately left open:Commit by commit (the new three):
test(integration): add the CFT composition fixture— simulator driving the composed artifact directly, plus shared helpers (test users,deployCft,actAs/registerAs,fundAs).test(integration): add the CFT composition spec suite— per-case specs following thespecs/<topic>/<case>.spec.tslayout; ports the removed unit suite's coverage and adds the conservation invariant (only paired mint/burn/burnFrom may movetotalSupply; transfer, approve/transferFrom,_move, sweep never do), a multi-user end-to-end flow, escrow burn-down/exhaustion, and memo-less-debit checks.test(integration): add CFT privacy and concurrency specs—privacy.specasserts from the public ledger only: balances/pending/escrows stay ciphertexts, the approve cap never appears in clear, equal amounts are unlinkable, transfer reveals the counterparty graph but no amount, mint/burn disclose amounts through the supply delta by design, and hostile wallets (wrong EK, overstated plaintext or allowance) fail the witness-binding checks.concurrency.specdocuments the same-block limitation from the module header by proving its cause deterministically: with the witness seed pinned, an identical credit replayed on a changed recipient pre-state yields a different transcript (two transactions proven against one pre-state conflict), credits to distinct recipients touch disjoint cells, and sweep contests the same pending cell an incoming credit writes.Testing notes
yarn test:integration(theintegrationvitest project;compile:integrationbuilds the composed artifact).tsc --noEmitandbiome ciare clean.unit-liveproject only globssrc/**/*.test.ts).PR Checklist
Further comments
Draft until #653 and andrew-fleming#10 settle; will rebase onto whatever shape they land in.