Skip to content

security: harden Basis state, signing, and settlement boundaries - #12

Closed
a-shannon wants to merge 43 commits into
BetterMoneyLabs:masterfrom
a-shannon:a-shannon/fix-basis-aggregate-debt
Closed

security: harden Basis state, signing, and settlement boundaries#12
a-shannon wants to merge 43 commits into
BetterMoneyLabs:masterfrom
a-shannon:a-shannon/fix-basis-aggregate-debt

Conversation

@a-shannon

@a-shannon a-shannon commented Aug 8, 2026

Copy link
Copy Markdown

Summary

This supersedes the original narrow aggregate-debt draft with the full reviewed
Basis remediation stack. The follow-up audit found that acceptance, persistent
state, legacy redemption, tracker publication, signing, and confirmation share
the same safety boundary and should not be merged as independent partial fixes.

The paired ChainCash contract-generation PR is
BetterMoneyLabs/chaincash#20.

This is hardening for the current testing-stage codebase. No fund loss is known
or claimed.

Findings addressed

  • collateralization could use an unmaintained reserve debt placeholder instead
    of the issuer's projected cumulative liabilities;
  • legacy proof/signature/redemption surfaces remained callable and settlement
    progress could be advanced without confirmed-chain evidence;
  • persisted note, AVL, generation, and publication state lacked complete
    reciprocal integrity/restart joins, allowing stale or mismatched roots to be
    treated as authoritative;
  • scanner HTTP 404 and partial-page failures could be confused with an
    authoritative empty snapshot;
  • outbound node requests, response bodies, and actor waits were not uniformly
    bounded;
  • the tracker publisher sent configured signing material to a node wallet API
    and trusted wallet-list JSON independently from the exact raw boxes supplied
    to the prover;
  • transaction presence alone was treated as confirmation without proving block
    inclusion, selected-chain ancestry, policy depth, freshness, or rollback;
  • the global v1 reserve AVL/domain model could not safely represent independent
    reserve generations, while malformed or oversized v2 admission data and
    output values needed fail-closed bounds.

Changes

Persistent state and publication

  • versioned, bounded snapshots with exclusive writer leases, generation/NFT
    manifests, strict restart replay, and terminal quarantine on unknown durable
    outcomes;
  • exact reciprocal joins between signed publication intent, pending receipt,
    confirmed projection, chain evidence, policy identity, and rollback state;
  • capacity, arithmetic, parser, proof, and serialized-size bounds with isolated
    negative fixtures;
  • publication health gates all confirmation consumers after an unexpected
    updater exit or integrity failure.

Chain confirmation and service bounds

  • confirmation derives from canonical signed bytes, exact successor state,
    pinned node-v6 transaction Merkle semantics, full-block inclusion, linked
    headers, selected-chain tips, depth/freshness policy, and durable reorg
    rollback;
  • HTTP uses one process-wide non-waiting 16-permit executor with a 3-second
    connect timeout, 15-second total timeout, and checked 2 MiB response cap;
  • updater-to-actor admission is bounded and every response has a deadline;
  • scanner 404, pagination failure, cancellation, and oversized-body paths
    preserve the previous authoritative snapshot.

Signing boundary

  • tracker updates are signed locally with ergo-lib; the configured secret is
    never serialized into a transaction artifact or sent to the node;
  • tracker and fee inputs are reparsed from canonical raw Sigma bytes and bound
    exactly to API id, value, ErgoTree, assets, registers, and height;
  • every fee input is token-free and owned by the same exact P2PK; change returns
    to that owner;
  • ten linked headers, the current nested node parameters, input cardinality and
    order, checked value arithmetic, post-sign context validation, broadcast
    bytes, returned transaction id, and journal bytes are cross-bound.

Legacy retirement and dormant v2 foundation

  • nine legacy construction/proof/signature/redemption routes return pre-effect
    HTTP 410; the obsolete CLI, TUI, actor commands, builders, and global reserve
    AVL surface are removed;
  • exact ERG/token v2 domains, fixed 32/8 tracker and 32/24 per-reserve trees,
    BNS2/BRS2 state, Schnorr/claim primitives, and bounded manifest admission are
    installed;
  • v2 remains deliberately disabled: there is no production v2 prover, user
    wallet signer, submitter, broadcaster, or public activation constructor.

Validation

Exact final tip: 9b7ebc74acf2b3880a18b29066a1f2ea9e04d6eb.

  • focused security matrix at the final merge: 62/62
  • full basis_server: 192/192
  • full basis_store on the unchanged reviewed integration parent: 253 passed,
    3 network tests ignored
  • workspace cargo check: pass
  • formatter, diff checks, independent exact-tip review, and full-history
    publication guards: pass
  • tests used public sigma-rust commit
    169211b9b59d12eb9b66ecb4fdb0d95699d194fa through transient Cargo overrides;
    no local dependency path is added by this PR

The broader all-target check still reaches an unrelated existing benchmark
error where secret_bytes() is called on [u8; 32]; that benchmark blob is
byte-identical on master and this branch.

Boundaries and maintainer decisions

  • This remains a draft for review, not a production-readiness claim.
  • No live node, funded transaction, signing, broadcast, deployment, or remote CI
    run was performed.
  • The configured node remains a trusted chain-observation source; this is not an
    SPV or multi-source verifier.
  • Tracker publication intentionally stays fail-closed until a maintainer sets
    the confirmation/retirement horizon.
  • Enabling v2 redemption still requires an internal prover/wallet integration
    to consume only the validated manifest and the exact bound reserve/funding
    boxes.
  • Existing v1 boxes require an explicit inventory and migration/retirement
    decision; this PR does not silently rewrite them.

Suggested review order

  1. state snapshots, generation binding, and legacy-route retirement;
  2. bounded HTTP/scanners and actor deadlines;
  3. fixed AVL/v2 domain and dormant admission primitives;
  4. confirmed-chain reconciliation and restart/reorg joins;
  5. local tracker signing and exact fee-input/change binding.

Fail closed on partial generation state, expose validated roots only through the tracker actor, and hold a monotonic lease across signing and broadcast. Port the overlapping public tombstones from containment commit 2c85486 without importing its unrelated CLI and documentation changes.
@a-shannon a-shannon changed the title fix: aggregate issuer debt in collateralization checks security: harden Basis state, signing, and settlement boundaries Aug 10, 2026
kushti pushed a commit that referenced this pull request Aug 12, 2026
@a-shannon

Copy link
Copy Markdown
Author

Closing this draft. Follow-up fixes will be submitted as smaller, independently reviewable PRs against the current master branch.

@a-shannon a-shannon closed this Aug 25, 2026
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