Skip to content

feat: bound Merkle proof depth at verification - #695

Merged
thlpkee20-wq merged 2 commits into
RevoraOrg:masterfrom
Bojest001:feat/proof-length-bound
Jul 29, 2026
Merged

feat: bound Merkle proof depth at verification#695
thlpkee20-wq merged 2 commits into
RevoraOrg:masterfrom
Bojest001:feat/proof-length-bound

Conversation

@Bojest001

Copy link
Copy Markdown
Contributor

Here's a concise PR description you can use:

───────────────────────────────────────────────────────────────────────────────────────────────

feat: bound Merkle proof depth at verification

Summary

Adds a hard upper limit on Merkle proof length at the verification entrypoint to prevent gas
exhaustion and memory overflow from adversarially crafted deep proofs.

What changed

src/merkle_helpers.rs

  • MAX_PROOF_DEPTH = 32 — public constant; covers any realistic snapshot (2³² leaves) while
    capping per-call cost
  • MerkleError::ProofTooDeep = 1003 — structured error returned by the helper
  • verify_merkle_proof(env, leaf_hash, root, proof) — new pure helper; O(1) depth check fires
    before any SHA-256 call

src/lib.rs

  • RevoraError::ProofTooDeep = 77 — frozen wire value, stable since v1
  • EVENT_PROOF_REJECT_DEPTH (prf_rej_d) — event emitted when a proof is rejected so indexers can
    observe oversized-proof attempts
  • pub fn verify_merkle_proof(env, caller, leaf_hash, root, proof) — read-only, auth-free
    contract entrypoint

src/test_merkle_proof_depth.rs (new, 18 tests)

  • Boundary: depth exactly 32 → Ok(true); depth 33 → Err(ProofTooDeep)
  • Event: prf_rej_d emitted on rejection; not emitted on valid proofs
  • Integration: build_merkle_root + verify_merkle_proof round-trip

docs/merkle-proof-depth-bound.md (new)

  • Rationale, API reference, error wire values, event schema, off-chain proof construction
    guide, change-compatibility table

Security

The depth check is O(1) and runs before any hashing — an adversary cannot trigger expensive
computation by submitting an oversized proof vector.

Testing

cargo test -- --test-threads=1

All 18 new tests in test_merkle_proof_depth plus the full existing suite must pass.

▸ Closes#571

Add MAX_PROOF_DEPTH = 32 to merkle_helpers, reject oversized proofs
with ProofTooDeep error (wire value 77), emit proof_reject_depth
(prf_rej_d) event on rejection, and expose verify_merkle_proof as a
read-only, auth-free contract entrypoint.

Changes:
- src/merkle_helpers.rs
  - Add MAX_PROOF_DEPTH: u32 = 32 constant (pub, documented)
  - Add MerkleError::ProofTooDeep = 1003 variant
  - Add verify_merkle_proof() helper with O(1) depth check before hashing
  - Expand module-level docs with proof verification section

- src/lib.rs
  - Add RevoraError::ProofTooDeep = 77 (frozen wire value)
  - Add EVENT_PROOF_REJECT_DEPTH (symbol_short!("prf_rej_d")) constant
  - Add pub fn verify_merkle_proof() contract entrypoint:
    emits prf_rej_d + returns ProofTooDeep when proof.len() > 32
  - Register test_merkle_proof_depth module

- src/test_merkle_proof_depth.rs (new)
  - 18 tests covering: constant value, valid proofs, depth-bound
    boundary (exactly 32 passes, 33 fails), contract entrypoint,
    event emission, and build+verify round-trip integration

- docs/merkle-proof-depth-bound.md (new)
  - Developer notes: rationale, API reference, error codes,
    event schema, off-chain proof construction guide, and
    change-compatibility table

Security: depth check fires before any SHA-256 call (O(1)),
preventing gas/memory exhaustion from adversarial deep proofs.
@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

Hey @Bojest001! 👋 It looks like this PR isn't linked to any issue.

If this PR is for one of the issues assigned to you as part of a Wave, please link it to ensure your contribution is tracked properly. You can do this by adding a keyword to the PR description (e.g., Closes #123), or by clicking a button below:

Issue Title
#571 Add snapshot proof-length bound assertion so proofs fit under contract memory limit Link to this issue

ℹ️ Learn more about linking PRs to issues

@thlpkee20-wq
thlpkee20-wq merged commit c46978a into RevoraOrg:master Jul 29, 2026
1 of 3 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.

2 participants