deviant/project-context.md
walerikus 518a3ce174 chore: initial project baseline — full Deviant codebase under version control
Brings the whole project into git (previously only the on-ramp feature and
a few parallel files were tracked). Includes: wallet core (src/), CashScript
contracts/, the Capacitor shell (shells/), scripts/, tests, and the docs
corpus (wiki/, snapshots/, Parameters/, Archive/, KnowledgeBase text).

Excluded via .gitignore: node_modules/, dist/, .env (secrets), testnet WIF
key files (.chipnet-*.json, devWallets.ts), KnowledgeBase/RAW media (~9.6 GB),
transcripts/ (session logs), and machine-local config (.claude/*.local,
*.lock). Secret-scanned before commit — no credentials in the tree.

Note: src/swapMath.ts, src/swapBuilder.ts, contracts/OpenMintToken.cash are
legacy (OP_RETURN era) but still imported; committed as-is, flagged for a
separate removal once de-referenced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:38:07 +02:00

21 KiB
Raw Blame History

Here is the project context document. Use it as reference for our session.

Synthesized from all 135 snapshot files in snapshots/ (read oldest-first by modification date, 0001-init → 0132-modest-...arithmetic-vote). This is a condensed master reference — for primary detail consult the individual snapshot, wiki/decisions.md (ADRs), and deviant_technical_spec_v2.7.md.


1. Project overview and goals

Deviant is a non-custodial Bitcoin Cash (BCH) wallet plus a token-economy protocol built on CashTokens and CashScript covenants. The author/owner is Anonymous, a BCH big-blocker advocate. The thesis: BCH's large-block, on-chain-first design makes it possible to build financial primitives directly on Layer 1 that other chains push off-chain — and to do so while eliminating trusted third parties wherever the chain can enforce a rule itself.

The recurring design principle, stated explicitly in the voting work and applied throughout: "What the chain CAN enforce, the chain SHOULD enforce." A UI is a reporter of consensus facts, never an authority.

Core product pillars:

  • ASM (Automated Swap Mechanism) — permissionless, BCH-backed token swaps with no DEX/AMM/oracle/operator. Every token UTXO is self-backed (carries its own BCH inside at a fixed rate); swaps are atomic single transactions enforced by consensus, not by coupled covenants.
  • MBA (Minted Backed Asset) — the backed-asset family. Each unit carries an intrinsic, consensus-enforced BCH backing redeemable unilaterally by the holder (no counterparty, oracle, or market needed). Sub-types: DEA (Direct Emission Asset / hard-backed), PLA (commodity), MCA (bond), MTA (tranche).
  • NBA (Non-Backed Asset) — assets with no per-unit consensus invariant: game currency (PTU), mineable coins (PTL), meme/tokens (MTU), NFT/collectibles (MTL). CDP-style stablecoins (DAI-shape) classify as PTU — collateral backs the debt, not the token.
  • DRA (Dynamic-Rate Asset) — MBA whose backing rate is a transparent, published, deterministic function of contract state (bonding curve, escalating/decreasing fee, exponential/step/arithmetic ladders).
  • Event/prediction markets — pari-mutuel "totes," oracle-settled bilateral escrows, and "Family D" collateralized binary-share markets (Polymarket-shape, CLOB + AMM).
  • On-chain governance — a bicameral-sortition voting system with anti-plutocracy economics, implemented as a stack of covenants (CitizenToken, ApplicationCovenant, RegistryState, BallotCovenant, EndorsementCovenant, ElderFreezeAction, ComplaintCovenant).
  • The CosmoGenesis wallet shell — a Capacitor + React app running the wallet core client-side in-WebView (non-custodial), with a four-tab IA: Main / Assets / Avalanche (create) / Apps (dApp connectors + Discover).

Process conventions: staged validation regtest → chipnet → mainnet; every milestone recorded as a numbered snapshots/NNNN-*.md; architectural decisions recorded as ADRs in wiki/decisions.md. The protocol's first end-to-end swap was validated on chipnet at snapshot 0008; 129+ swaps have run since with zero exploits.


2. Key architectural decisions (chronological)

Early foundational pivots (snapshots 0001–0020):

  • 0001–0003 — TS + CashScript SDK stack; OP_RETURN-tagged token design; regtest harness via MockNetworkProvider (no Docker).
  • 0004 (ADR-0006) — Pivot to CashTokens. OP_RETURN tagging abandoned; CashTokens FT becomes the consensus primitive, BCMR for metadata, rate floor raised to 1000 sats/unit. ADR-0004 superseded.
  • 0007–0008 — Self-backed UTXO model + reservoir model. Each FT UTXO carries tokenAmount × backingRateSats of BCH inside it; redemption is a plain P2PKH spend (contract-free). Full FT supply (up to 2⁶³−1) is pre-minted at genesis into a contract "reservoir"; claim() drains it at the protocol rate. Q4 answered YES on chipnet (0008): a single tx can atomically redeem one token and mint another — atomicity is BCH-level, not covenant-coupled. Category bytes use consensus LE ordering (txidToConsensusBytes = hexToBin(hex).reverse()).
  • 0009 — Open-mint validated cross-wallet: anyone can reconstruct a contract from public params and claim; no founder approval needed when founderFeeBps=0.
  • 0011–0012, 0017–0020 — Threat model established. The rate-peg check (output[recipient].value == amount × rate) is the single load-bearing security invariant; without it a contract is trivially drained (V-002). Other threats: V-001 rogue minting NFT (mitigated by output-cap / picker filter on nft.amount > 0); T-001 non-canonical "backdoor" contract issuing underbacked FTs (mitigated by D-1 + D-2); T-002 B-model definition poisoning (irreducible; mitigated by wallet friction D-4..D-8).

The verify/defense layer (snapshots 0022, 0031):

  • D-1 — canonical contract verification: reconstruct the canonical template with published params, compare P2SH32 address and byte-exact redeem script on chain (0031 removed the collision-resistance caveat). Pinned bytecode hash is the third independent layer (ADR-0008 Decision A: embedded canonical artifact, not a signed manifest).
  • D-2 — per-UTXO backing check: expected = units × rate; flag UNDERBACKED and exclude from redeemable balance.
  • D-3 — verification source: canonical artifacts embedded as JSON imports (0052) so the core bundles for browser with no fs/path.

Mid-arc taxonomy and asset-class ADRs:

  • ADR-0015 (0027/0037) — Dynamic-Rate Asset (DRA) recognized; transparency of the curve is mandatory (a masked single rate is a T-003 masquerade attack). Multi-template D-1.
  • ADR-0025 (0044/0049) — obligor-free MBA (backing intrinsic + present, not a third party's promise) + denomination schedule (display decimals scale with order of magnitude; BCH's 8 decimals is the ceiling).
  • ADR-0026 (0053) — CosmoGenesis four-tab UI + glossary (ASM = Automated Swap Mechanism).
  • ADR-0027 (0054) — NBA = Non-Backed Assets family (replaces "Token" label).
  • ADR-0028 (0055) — per-class real-world peer labels; stablecoins (USDT/USDC) reclassified MTU; consensus-backing test for MBA membership.
  • ADR-0029 (0058/0059) — stepped founder fee accepted; supply trigger is canonical (feeBps = min(base + (issued/step)·feeStep, maxFee)); decreasing-fee sibling promoted; block-height trigger rejected (tx.time not readable as an arithmetic value, only a CLTV lower bound).
  • ADR-0030 (0060) — Family D collateralized binary share market (Polymarket model): fixed-terminal-value shares, split/merge invariant 1 collateral → 1 YES + 1 NO, oracle-settled, no pro-rata residual.
  • ADR-0031 (0065/0075) — oracle-priced vault / synthetic-USD hedge leg. Amendment named two rejected dynamic-rate-MBA "stablecoin" variants (minting price ≠ a maintained peg).
  • ADR-0032 (0066) — ExpiringMBA: time-boxed self-backed instrument; "automatic expiry" = consensus time gate (CLTV) + permissionless conversion to a fixed owner. Nothing is truly automatic on UTXO (no scheduler).
  • ADR-0033 (0067–0073) — CDP stablecoin taxonomy, 9 decisions. Headline: collateral backs the debt, not the token; CDP token is PTU (unbacked). "Secured ≠ backed." The volatility paradox (Decision 7): the asset marketed as safe is the one whose advertised property fails under stress; an MBA promises nothing it cannot keep. Value-flow asymmetry (Decision 9): upside always flows past the stablecoin holder.
  • ADR-0034 (0069) — buyer-funded PoS cashback is a wallet tx-construction feature, not a covenant (a locking script runs only when its own UTXO is spent, never on receipt).
  • ADR-0035 (0075) — BCH as a self-custodied USD rail; four-option matrix (raw BCH+ASM / synthetic-USD hedge / custodial USD-on-BCH / oracle-stamped transit receipt); Deviant's contribution is the assembly, not the primitives.
  • ADR-0036 (0080, 0085, 0092) — on-ramp providers in Apps→Discover; ranking = transparency, not endorsement (three never-merged signals: objective facts, external plural reputation via kycnot.me, device-local user rating). External link-outs; Tier-3 transactional API deferred (later narrowly admitted for SideShift in 0103).
  • ADR-0037 (0087) — supply semantics: (A) seed reservoir at 2⁶³−1 so "depletion" is a non-event for circulating MBAs; (B) Token-family supply is not scarcity.
  • ADR-0039 (0101, refined 0104) — MBA divisible by default. Atomic floor pinned at dust-safe 1000 sats; decimals carry value. Refined to a uniform 2-decimal default (clamping only when the whole-unit rate isn't cleanly divisible). New creations only — deployed artifacts are immutable.
  • ADR-0040 (0107, + Addenda) — voting systems: three primitives (PollCovenant allowlist / TallyState trustless tally / StakeVoteTote stake-weighted); sybil resistance lives upstream (issuer allowlist or sortition); co-spend-as-oracle idiom; bicameral sortition + adaptive bootstrap + Elder/founder tiers; removal-bond and per-vote-fee economics.

Shell / platform decisions:

  • ADR-0022 (0041) — embed nodejs-mobile for the mobile shell → SUPERSEDED same-era.
  • ADR-0023 (0042) — crypto shim: replace libauth WASM with @noble at build time, proven byte-for-byte, so one in-process core runs in any JS engine. This is the current crypto backend.
  • 0043–0044 — mobile shell reopened; Capacitor spike → GO. Core runs client-side in the WebView with no nodejs-mobile and no IPC; converges mobile/desktop/web onto one in-WebView core.

3. Important code patterns and mechanisms worth preserving

  • Self-backed UTXO / reservoir / claim: the heart of the protocol. claim(amount, recipientLockingBytecode) mints from the reservoir and the contract enforces output shapes: [0] reservoir back, [1] FT to recipient backed at rate, [2] optional founder fee. Output count is capped and trailing outputs checked for zero tokenCategory (V-001 fix).
  • The rate peg — the one invariant that must never be removed: require(tx.outputs[i].value == tokenAmount × backingRateSats). Pegged tokens cost ~10²¹ sats to drain (impossible); unpegged cost ~675 sats (free). 18 orders of magnitude.
  • Atomic swap — two inputs (source FT P2PKH spend + target reservoir/minting NFT), one tx. The source side releases whatever BCH its UTXO carries; the target claim() mints at whatever rate it computes. ASM is rate-function-agnostic. A 1% fee produces a consensus-enforced ~2% round-trip bid/ask spread.
  • Carried-rate trick (DRA / escalating NFTs): store the current rate/price in a mutable NFT commitment at the contract address; read it via int() (CashScriptNum round-trips cleanly), enforce payout, then ratchet the commitment (×multiplier, +increment, etc.). Un-resettable because the position UTXO returns to the contract address. CashScript has no pow/loops, so escalation is done by reading carried state, and batch buys use bounded unroll (fixed N: claim3(), claimBatch(k ≤ remainingInTier)) rather than a variable claimMany(n).
  • Co-spend-as-oracle: one covenant attests by reading another covenant's NFT-commitment state in the same transaction (no signer, no external oracle). General idiom used in totes, Family D, and the voting tally primitives. Pin layout by fixed tx.inputs[i], not this.activeInputIndex, to avoid re-execution at input 1.
  • checkDataSig oracle settlement: 16-byte message, all uint32 LE (timestamp, sequence, contentSequence, price). Same format used by AnyHedge and Paryon PriceContract. Verifies that a key signed, not the truth of the claim.
  • Two-phase plan/execute: every mutating wallet op splits into plan* (pure, previewable) and execute* (signs + broadcasts). Reifies D-5 friction (BCH magnitude shown before consent). Pre-broadcast audit gate refuses txs implying illicit minting. CLI is preview-only unless --yes.
  • Contract-free batch burns: redeem-all (all MBAs → BCH at peg), sweep-tokens (non-MBA categories → raw sats), swap-all <target> (redeem-all then claim, non-atomic with a first-class resume path). All are P2PKH spends — work on any registered MBA regardless of contract type. Only claim (covenant mint) needs per-template integration.
  • Dependency-injected chain layer: the pure core (src/) is tested with no network; runtime.ts provides ElectrumUtxoSource, broadcaster, and connectWallet(). Barrel index.ts excludes runtime so pure consumers avoid cashscript/mainnet-js.
  • Dust facts: CashToken FT outputs need 675 sats minimum (vs 546 P2PKH) due to the ~42-byte token prefix. Sub-dust FT remainder is folded into the burned amount rather than left unsendable. Founder fee output must clear 546 sats.
  • KeyStore contract (src/wallet/keystore.ts): platform-agnostic key-custody seam; each shell implements once (WebKeyStore AES-GCM/PBKDF2; CapacitorKeyStore Keychain/EncryptedSharedPreferences + biometric). R-017 fix (0100): create() and restore() must both derive at the canonical BCH path so funds are visible to standard wallets.

4. What was tried and abandoned (and why)

  • OP_RETURN-tagged token architecture (0001–0003) → replaced by CashTokens FT (ADR-0006); the consensus primitive made it obsolete.
  • Mutable post-genesis FT supply (assumed pre-0008) → CashTokens fixes supply at genesis; adopted the reservoir model instead.
  • nodejs-mobile embedded runtime (ADR-0022) → superseded by the noble crypto shim (ADR-0023); replacing WASM at build time let the same core run in any JS engine, with no IPC.
  • Block-height fee-escalation trigger (0058) → rejected; tx.time is only a CLTV lower bound, not adversarially enforceable as an arithmetic value. Supply trigger is canonical.
  • Tier-2 NFT-free tote first then NFTs ruled out (0047) → reversed by ADR-0024 Addendum 2 (0048): NFTs permitted as covenant machinery, not collectibles — enabling covenant-enforced double-claim guards.
  • Two dynamic-rate "stablecoin" MBA variants (ADR-0031 amendment, 0075) → rejected: a minting price is not a maintained peg; funding recalibration either does nothing or collapses into the already-covered hedge model.
  • Pool-funded / circular cashback (0069) → rejected as circular; cashback is buyer-funded.
  • Two-slider founder-fee (feeRate + maxFeeRate) UI fiction (0082) → removed; covenant bytecode is immutable, so a single flat slider with a lock icon is honest.
  • Off-chain pre-gate endorsement counting (0120) → abandoned (0124, user correction): an off-chain attestation reintroduces a trusted verifier — the exact manipulation surface the design exists to remove. Replaced by on-chain EndorsementCovenant. The "too expensive on-chain" argument was also shown false (~$0.15/day at 100 admissions/day).
  • Dead-man's switch (founder mitigation Layer 6) (0112) → removed; conflicts with the founder's hands-off reserve role. Replaced by elevated multi-chamber demotion paths.
  • Two-chamber interim governance (0111) → dropped; a candidate-controlled "friend" chamber was a capture weakness. Replaced by three-stage gating (independent pre-gate + two sortitioned chambers).
  • Escalating-backing anti-plutocracy vote asset (0125) → corrected (0126): backing must be fixed and always-redeemable; only the non-recoverable fee escalates. A voter must never hold more than baseBacking recoverable per vote.
  • Variable-N batch claim claimMany(n) (0129) → impossible without pow (final commitment r·mⁿ + geometric sum); replaced by fixed-N bounded unroll. Sequential claim() is economically identical with no cap and is the default UX.
  • Deviant-hosted aggregate on-ramp ratings (0080) → rejected; no accounts ⇒ no sybil resistance. Device-local ratings only.

5. Current state and what's left to do

Wallet core (src/) — feature-complete and live-validated on chipnet. ~445 unit tests passing. Operations proven on live chipnet: balance, claim (incl. decreasing-fee DeviantDescFeeSupply covenant), swap, tier-A send, tier-B send, redeem, redeem-all, sweep-tokens, swap-all (both directions). D-1/D-2/D-3 verify layer in place. SQLite + LocalStorage registries. CLI (deviant …) and a local web UI both wired over the same runCommand seam.

Assets validated on chipnet: ASM/ASM2 (fixed-rate), metal MBAs GLD/SLV/CUP (decreasing-fee, max-reservoir) plus divisible variants GLDd/SLVd/CUPd. Route B made DeviantDescFeeSupply a first-class wallet asset (genesis → verify → claim → display, with founder fee correctly accruing).

Shell (CosmoGenesis, Capacitor + React) — UI-complete, runs core client-side non-custodial. All four tabs + Settings; live balance/class derivation; swap flow with live rates + route detection + two-phase broadcast; on-ramp Discover (provider cards, KYC/reputation chips, jurisdiction gating, SideShift Tier-3 in-wallet shift); seed-sweep; QR (qrcode.react); activity history; token import; code-split bundle (~315 kB app). Loading splash + manifesto UX. PWA beta deployed live at testchipnet.duckdns.org (chipnet + testnet4 only, mainnet structurally absent, non-dismissible beta banner, Let's Encrypt TLS).

Event/prediction + Family D — chipnet-validated spikes. Totes (binary, K=4, MBA-denominated, operator rake, refund/sweep); Family D configs 1–3 (BCH CLOB, MBA CLOB, fungible two-category), resting limit orders, SharePairAMM, oracle-priced vault, ExpiringMBA.

AnyHedge / ParyonUSD integration track (multi-turn, ~6–9 turns). Turn 0 compat validated (all 11 critical contracts compile under cashc 0.12.1, repos pinned). Turn 1 (AnyHedge half) chipnet-validated: maturity settlement + liquidation paths match the BCH-frame simulation exactly. Turn 2 (Paryon half — bootstrap 7 contracts, borrow/liquidate/redeem) is scoped and pending. Turn 3 (composition + triggers) and the DeviantHedgePair tradeable-FT design (Turns 4–6) follow.

On-chain governance (ADR-0040) — Phases A–F + EndorsementCovenant complete on chipnet. CitizenToken, ApplicationCovenant A→E (single-chamber → bicameral → anti-grinding cap/fail-fast → paid-regardless escrow → commit-reveal secret ballot), RegistryState (adaptive threshold), BallotCovenant, EndorsementCovenant (on-chain pre-gate), ElderFreezeAction, ComplaintCovenant. A full spectrum of anti-plutocracy DRA curves proven on chipnet (linear/arithmetic, exponential ×2/×10, step/tiered, super-exponential (r·3.14)³, dual-ladder). Phase G remains: canonical templates + wallet UI + regulatory pass; plus RemovalBondEscrow/TreasuryVault wiring and lazy-voter instrumentation.

Remaining / deferred across the project:

  • Native device builds (Android Studio / Xcode) — runbook ready, needs the SDKs; iOS WKWebView + biometric/camera plugins unproven on-device.
  • Mainnet validation + per-jurisdiction availability gating + regulatory counsel (R-016 blocking for any real-money pilot).
  • Live re-verification of on-ramp Tier-2/kycnot.me API shapes before mainnet.
  • Wallet-side genesis of DRA/descfee/escalating MBAs (claim already works; genesis UI builds only the canonical contract today).
  • Spec amendment for the max-reservoir recommendation (ADR-0037 A).
  • scripts/snapshot.mjs numbering bug (uses length+1 not max+1) — repeatedly flagged, manually worked around (note the duplicate-numbered snapshots in the history).

6. Open questions and unresolved issues

  • Oracle price-freshness binding — load-bearing and production-blocking for every price-triggered instrument (ADR-0031 hedge, ADR-0033 CDP analog, OraclePricedVault). Covenants can verify that an oracle key signed but not when; no freshness bound is enforced yet.
  • MBA-floored meta-stable / basket-stable (usd-rail §4.4) — design candidates needing pressure-testing on governance, rebalancing triggers, eligibility, maturity rollover, and regulatory bucket before any ADR.
  • B-model definition poisoning (T-002) — irreducible by design; only mitigated by wallet friction and ecosystem plurality (D-4..D-8). B-model is restricted to closed, trusted groups; surfaced as "Drafts / Labels," not real tokens.
  • Founder permanence in the governance design — retained against the usual sunset recommendation ("look what happened to Bitcoin without Satoshi"); flagged for a possible dedicated ADR if it becomes contentious.
  • CDP round-trip without triggers — the killer scenario in the BCH-frame simulation (−37.7% BCH): the CDP loss is permanent while the hedge BCH gain reverses. Trigger-based defenses recover it but assume idealized timing and add an oracle-trust assumption.
  • Family D / tote multi-outcome (K>2) — Approach #1 (fixed K=4 inline totals) is validated; per-outcome sub-pool and merkle-accumulator approaches for arbitrary K are still open.
  • CashConnect co-sign payload mapping — WcTransactionObject → SignTransactionV0Params[] differs from WalletConnect; device validation of CashConnect/WizardConnect handshakes deferred.
  • Governance hardening still on paper — CLTV announcement delays, strict 3/3 unanimous Elder freeze (MVP uses 2), elevated demotion path on-chain, per-complainer fee ramp, treasury-routing of bonds/fees, lazy-voter detection.
  • Knowledgebase corpus drift — older HTML overview files retain pre-ADR-0027/0033 framing ("soft-backed," old taxonomy); intentionally left until a full corpus repaint.