Skip to content

feat(confidential)!: make revoke_spender proofless - #854

Draft
brozorec wants to merge 1 commit into
feat/conf-token-auditor-escrowfrom
feat/conf-token-proofless-revoke
Draft

feat(confidential)!: make revoke_spender proofless#854
brozorec wants to merge 1 commit into
feat/conf-token-auditor-escrowfrom
feat/conf-token-proofless-revoke

Conversation

@brozorec

Copy link
Copy Markdown
Collaborator

Stack 2/3. Base: feat/conf-token-auditor-escrow (#853). Followed by clawback.

Review #853 first — this PR's safety argument depends on it. Merge #853 before this one, or GitHub will show its commits here too.

What

Deletes the RevokeSpender circuit. Revocation becomes a homomorphic fold: C_spend += C_a, then delete the delegation entry.

  • circuits/revoke_spender/ and its VK removed (−1144 lines)
  • revoke_spender(e, owner, spender) — no data, no proof
  • RevokeSpenderPayload / RevokeSpenderData dropped
  • RevokeSpender event reshapes to (a_tilde, allowance_salt)
  • on_revoke_spender loses its payload argument
  • CircuitType::RevokeSpender removed, vacating discriminant 5

Why the proof was redundant

The fold is pure homomorphic addition, exactly like merge (DESIGN §7.4): nothing is re-randomized, no private value is asserted. The escrowed amount was range-proven when the delegation was created and re-bounded on every spender transfer, and the next spend re-bounds the result. The circuit proved nothing the protocol did not already know.

The auditor stays in sync because #853 hands it dvk_i (S14/O_a9), from which it derives r_a = derive_allow_r(dvk_i, σ_a). Folding an allowance the auditor cannot open would desync its accumulator permanently — that is the dependency on #853, and the reason this PR cannot land first.

The event carries a_tilde and allowance_salt because the fold deletes the entry that held them and no other event carries either: SetSpender emits neither, and SpenderTransfer emits the salt it consumed, not the one it wrote. Both are public storage values, so emitting them discloses nothing new.

⚠️ Open question for reviewers: discriminant 5

This PR vacates CircuitType::RevokeSpender = 5; PR 3 reissues 5 as Clawback. A post-change token pointed at a pre-change verifier registry would fetch the retired circuit's key under discriminant 5, and nothing in the verifier can detect the mismatch.

Clawback = 6 costs nothing — the enum is not dense-packed and no on-chain value is saved by filling the hole. Recommend taking the free win rather than documenting the hazard. Flagging here because this PR is where the discriminant is freed.

Checks

nargo test 134 passed · cargo test -p stellar-tokens 713 passed · cargo +nightly fmt --check clean · cargo clippy --all-targets clean · constraints.baseline regenerated

Revocation folds the escrowed allowance commitment back into the owner's
spendable commitment by homomorphic addition, exactly like merge (DESIGN
§7.4). The escrowed amount was range-proven when the delegation was created
and re-bounded on every spender transfer, and the next spend re-bounds the
result, so the RevokeSpender circuit proved nothing the protocol did not
already know.

The auditor stays in sync because it can now derive the allowance blinding
from the escrowed dvk_i (S14 / O_a9).

BREAKING CHANGE: revoke_spender drops its `data` argument, the RevokeSpender
event carries `(a_tilde, allowance_salt)` instead of the checkpoint fields,
`on_revoke_spender` loses its payload, and CircuitType::RevokeSpender is
removed.
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

1 participant