Skip to content

Fix balance width - #831

Open
andrew-fleming wants to merge 9 commits into
OpenZeppelin:release/v0.3.0-alpha.1-rc.0from
andrew-fleming:fix-balance-width
Open

Fix balance width#831
andrew-fleming wants to merge 9 commits into
OpenZeppelin:release/v0.3.0-alpha.1-rc.0from
andrew-fleming:fix-balance-width

Conversation

@andrew-fleming

Copy link
Copy Markdown
Contributor

Resolves #795

@andrew-fleming
andrew-fleming requested review from a team as code owners August 27, 2026 04:50
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a0100448-e8b3-409a-82c3-eb6889282ed9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

await cft.register();
});

it('spends a balance accumulated past the per-transfer bound', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 blocking: The audit names debit, approval, and escrow spend as the locked paths; this covers only the _debit site (via _burn), leaving the approve claim site (ConfidentialFungibleToken.compact:908) unpinned. Extend it: cache 2n * MAX128, approve(BOB, MAX128), then complete with transferFrom.

added by claude (dev3-midnight-basic-review)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added 7a7274e

// invariant here instead of leaving it to inspection of those two circuits.
// The cast fails closed, so an out-of-range claim aborts rather than wraps.
const escrowPlaintext =
wit_PlaintextBalance(entry.spenderCt) as Uint<128>;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 blocking: "The cast fails closed" has no pinning test. Cache (1n << 128n) + escrowValue for the spender's escrow ct and expect transferFrom to throw — a truncating cast would make it succeed silently (the truncated value equals the real escrow), so that test discriminates exactly.

added by claude (dev3-midnight-basic-review)

@andrew-fleming andrew-fleming Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added 7488787

await cft._burn(MAX128);
});

it('keeps the transfer bound at the Uint<128> maximum', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 blocking: This pins the bound's value but not the widths on the compiled circuit: narrowing the witness to e.g. Uint<136> passes both new tests while collapsing the headroom from 2^120 to 2^8. Assert from MockConfidentialFungibleToken's contract-info.json that wit_PlaintextBalance's result maxval is 2^248-1 and transfer's value arg is 2^128-1 (parse bigint-aware — both exceed double precision).

added by claude (dev3-midnight-basic-review)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added 05c3670

pk: JubjubPoint,
ek: Bytes<32>,
claimedValue: Uint<128>
claimedValue: Uint<248>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 blocking: MockElGamal.compact:116 still declares claimedValue: Uint<128> — it compiles (implicit widening) but misstates this signature and makes a >2^128 claim untestable at the ElGamal level. Widen the wrapper and add one unit test claiming 2n * MAX128 against addCiphertexts(encrypt(pk, MAX128, r1), encrypt(pk, MAX128, r2)).

added by claude (dev3-midnight-basic-review)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed 8122aa1

* wrong plaintext fails the decryption check. Lifted special case of
* `assertDecryptsToPoint` with the message point `g^claimedValue`.
*
* @notice `claimedValue` is the widest `Uint` Compact offers, so this parameter

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 followup: The safety bound is ℓ, not the language cap — they coincide by only ~4 bits (2^248 < ℓ ≈ 2^251.86). One sentence stating the injectivity precondition (claim domain below the subgroup order) prevents a naive widening if the compiler cap ever rises past 251.

added by claude (dev3-midnight-basic-review)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added 2093f35

* `2^48` cap that kept wallet-side BSGS tractable is gone. Amounts stay well under
* the Jubjub scalar-field order, so the homomorphic balance sums (and the
* `g^value` encoding) do not wrap. Balances remain Uint<128>.
* `g^value` encoding) do not wrap.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: With accumulation, sums can wrap mod ℓ after ~2^124 maximal credits — same resource-bound class as the 2^120 paragraph below, and post-wrap the balance decrypts to sum mod ℓ (silent value loss, not lock). Worth the same qualifier here.

added by claude (dev3-midnight-basic-review)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed 320aff0

@0xisk 0xisk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! left some comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants