Skip to content

feat!: spec 17 - shield proof (circuit 3), native-asset-only pool, crates bumped (node/runtime 0.3.0) - #155

Merged
nol4lej merged 1 commit into
mainfrom
feat/spec-17-shield-proof
Oct 6, 2026
Merged

nol4lej merged 1 commit into
mainfrom
feat/spec-17-shield-proof

Conversation

@nol4lej

@nol4lej nol4lej commented Oct 6, 2026

Copy link
Copy Markdown
Member

Summary

Runtime spec 17 / tx 5. A shield must now prove that its note is worth exactly the deposit.

Before this change, nothing tied a shield's commitment to its amount: a deposit of 1 could insert a note worth 1000, and unshielding that note drained other depositors' funds.

Shield proof (circuit 3)

  • New circuit id 3 (shield). Public inputs are commitment, value, asset_id, with the same arity at every version.
    • primitives/zk-verifier: CIRCUIT_ID_SHIELD, SHIELD_PUBLIC_INPUTS, and has_memo_layout. Only transfer and unshield bind memos.
    • pallet-zk-verifier: CircuitId::SHIELD, ShieldStatement, ZkVerifierPort::verify_shield_proof, and encode_shield.
    • Registration accepts a shield key only with 3 inputs, at every version.
  • shield(asset_id, amount, commitment, encrypted_memo, proof, circuit_version) is checked in this order:
    1. Everything that does not need the proof: asset, amount, memo, canonical commitment, duplicates.
    2. The proof, against the deposit exactly as the call states it.
    3. Only then, the funds move.
  • shield_batch: each entry carries its own proof and version. One bad proof reverts the whole batch.
  • Weights add one verification per deposit.
  • EVM precompile: shield(uint32,bytes32,bytes,bytes,uint32), selector 0xf25897e0 (was 0x9feb22ea). The old calldata reverts.

Native asset only

The pool always moves T::Currency, so a note of a verified non-native asset was backed by ORB. shield, unshield, private_transfer and claim_relay_fees now refuse any asset other than NATIVE_ASSET_ID with AssetNotSupported, through AssetOperation::ensure_movable.

Multi-asset support stays in place: assets are still part of the commitment and there is still a balance per asset. Enabling another asset only needs a fungibles backend and relaxing that single check.

Refactor

  • ShieldOperation::execute(depositor, &proof, ShieldRequest) has the same shape as unshield and transfer. ShieldRequest::from_batch_item splits a batch entry.
  • Proof / MAX_PROOF_SIZE (512) is the single proof bound. Every call and the precompile use it. The encoding is unchanged.

Versions

Crate Version
orbinum-zk-verifier 2.1.0
pallet-zk-verifier 0.14.0
pallet-shielded-pool 0.21.0
pallet-evm-precompile-shielded-pool 0.8.0
orbinum-runtime / orbinum-node 0.3.0

Changelogs and RUNTIME_VERSIONS.md (spec 17) are updated. scripts/vk/workflows/setup-dev.sh also registers shield.

Test plan

  • cargo test: pallet-shielded-pool 390, pallet-zk-verifier 128, precompile 91.
  • pallet-shielded-pool with skip-proof-verification + runtime-benchmarks: 387.
  • Real shield proof (circuits 0.16.0) verified against the published VK. It is refused with another amount, another asset, another commitment, or a non-canonical commitment (c + r).
  • Retired and unregistered shield versions are refused without falling back. Each batch entry is verified against its own deposit.
  • cargo clippy --all-targets: no warnings. cargo check -p orbinum-runtime --features runtime-benchmarks passes.
  • --dev node, e2e-shield-live.cjs: 71/71.
    • Includes adversarial cases: non-native asset, a batch with one bad proof, msg.value refunded on revert, offsets past the calldata or pointing at the memo.
  • --dev node, e2e-shield-clients-live.cjs: 37/37.
    • Covers wallet-sdk + ts-protocol, the extrinsic, the precompile and shieldBatch.
    • Includes a rotation of the shield VK to v2 with v1 retired.

@nol4lej
nol4lej merged commit 94b65ba into main Oct 6, 2026
6 checks passed
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