Skip to content

DLV claim/invalidation move no value — incomplete settlement machinery, stranded funds #451

Description

@cryptskii

Summary

The DLV (Deterministic Limbo Vault) lifecycle is not a closed settlement protocol in code. create and unlock
have real, self-contained effects, but claim and invalidation move no value — they flip an in-memory enum
and return unsigned operations whose balance handlers are explicit no-ops, and the SDK discards those operations.

Severity: Medium (correctness / stranded funds — not an active exploit). This is incomplete settlement
machinery, not a mint vulnerability: the credit paths were deliberately disabled because wiring them naively
enabled arbitrary mint (per the module's own notes on the reverted PR #196). The real risk is stranded funds
(DlvCreate debits the creator, but invalidation never re-credits) plus a false API contract (claim returns
Ok while settling nothing).

Evidence (dsm_client/deterministic_state_machine/)

  • Create (real, in-memory + debit): dsm/src/vault/limbo_vault.rs:1035,1210 (crypto), dsm/src/vault/dlv_manager.rs:98
    (in-memory HashMap insert + unsigned DlvCreate). The one real value movement: dsm/src/core/token_state_manager.rs:360-396
    debits the creator by locked_amount (insufficient-balance check at :379).
  • Unlock (real predicate verification, state-only by design): dsm/src/vault/limbo_vault.rs:1895 (verify_fulfillment,
    then state = Unlocked); token_state_manager.rs:424 ("DlvUnlock is a state-only transition — no balance change"). Correct.
  • Claim — not wired: dsm/src/vault/limbo_vault.rs:1991 flips local state only (:2035,:2093), dBTC path
    defers to draw_tap (:2028); dsm/src/vault/dlv_manager.rs:241 returns an unsigned DlvClaim with only a
    proof hash (no token_id/amount/claimant credit); balance handler is a no-op
    (token_state_manager.rs:413-422, let _ = claimant_public_key;); SDK discards the op
    (dsm_sdk/src/sdk/dlv_sdk.rs:475, let (content, _op) = ...).
  • Invalidation — not wired: dsm/src/vault/limbo_vault.rs:2112 flips state only (:2145, no fund return);
    dlv_manager.rs:267 returns unsigned DlvInvalidate; balance handler is a no-op
    (token_state_manager.rs:399-411); SDK discards the op (dsm_sdk/src/sdk/dlv_sdk.rs:497).
  • The module documents its own gap: dsm/src/vault/dlv_manager.rs:10-47DlvClaim/DlvInvalidate are
    "unsigned signals — they do NOT themselves mutate token balances"; lists the per-vault state registry / claim
    availability proof required by SoFi §10.3 as "NOT enforced"; notes PR core/token: unresolved tokens fall back to synthetic policy commits and DLV claim/invalidate remain non-atomic #196's naive credit path was reverted
    because the fork lacks the registry and "the self-attested credit path enabled arbitrary mint."

dBTC vaults are masked because they carry locked_amount = None and settle out-of-band via
dsm_sdk/src/sdk/bitcoin_tap_sdk.rs (draw_tap, mint/burn against Bitcoin SPV proofs). The token-ledger DLV path
is the dead one.

What closure requires

  1. A per-vault encumbrance/claim registry (SMT leaf keyed by vault_id, Created→Claimed/Invalidated) consulted
    atomically so locked_amount releases exactly once (prevents double-claim across stitched receipts). Scaffolding
    exists in dsm/src/dlv/vault_smt_leaf.rs / vault_state_anchor.rs but is not consulted by claim/invalidate.
  2. Carry token_id + locked_amount on Operation::DlvClaim / DlvInvalidate and implement the credit/restore
    branches in token_state_manager.rs:399/:413, gated on the registry.
  3. Stop discarding the operation in dsm_sdk/src/sdk/dlv_sdk.rs:475,497 — sign and submit it through the
    transition path so the delta is part of an authoritative, hash-chained receipt.

Affected files

  • dsm_client/deterministic_state_machine/dsm/src/vault/limbo_vault.rs
  • dsm_client/deterministic_state_machine/dsm/src/vault/dlv_manager.rs
  • dsm_client/deterministic_state_machine/dsm/src/core/token_state_manager.rs
  • dsm_client/deterministic_state_machine/dsm_sdk/src/sdk/dlv_sdk.rs
  • dsm_client/deterministic_state_machine/dsm/src/dlv/{vault_smt_leaf.rs,vault_state_anchor.rs}

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpriority:mediumMedium priorityrustPull requests that update rust code

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions