Snapshot commit rolling up ~255 files of coherent-but-multi-domain in-flight
work that had accumulated on this branch. Split by area:
Contracts + covenants
- New: AsmFxSwap, DeviantOpenMintNBA, DeviantTieredMintOracleFT,
TermCouponVault, UniformReserve, UniformReserveAggregate.
- Verify-artifact refresh (src/verify/artifacts/*.json + canonical.ts).
Wallet + shell (shells/app + src/wallet)
- App.tsx, MainScreen, ArtemisionScreen, AssetDetail, AgoraScreen,
SettingsScreen, Unlock, TokenImportModal, UniformFiat/DepositPanel,
KatalogosPanel (renamed from PinaxPanel), shell.css.
- src/wallet: wallet.ts, runtime.ts, index.ts. Core registry/chipnetFile.
- Deleted stale hook: useAllDevBalances.ts.
Cross-chain + correspondent (services/correspondent + scripts)
- Correspondent server/bch/config updates for PYUSD Solana, EURC Sepolia,
aggregate reserve flows.
- New scripts: PYUSD roundtrip, EURC onboarding, GMX game loop /
genesis / mint sanity, tiered mint fee, aggregate reserve, product2
shares dividends, product3 t-bond, uniform fiat cell tests.
Telegram order-book (P2PExchange bot)
- db.ts, index.ts, en/ru locales — updates upstream from the extracted
standalone repo at D:/Dev/P2PExchange.
Docs — Parameters (specs), wiki, snapshots, design mockups
- Parameters: FIATm/MBA_Shares/Potidaea/Anthemus refinements +
ASM_CrossChain/DebitCredit + UniformFiat + Anthemus DEX MVP prompt +
Artemision + Athenae Politeia + Philosophy + SSHkeyServer runbook +
new dApp/{Artemision,Katalogos,Pinax,Pari_escrow,SURFACES}.
- wiki: cross-chain, games-tote, glossary, governance/voting-systems,
infra, wallet, wallet-ui-design, decisions (ADR log).
- snapshots: catch-up entries and INDEX regeneration.
- design: mockups refreshed (agora, asset-detail, assets-tab, potidaea)
+ Potidaea assets + tote deploy notes.
Housekeeping
- .gitignore: exclude the new root test/session state files
(.sol-vault-keys.json, .football-tote-state.json,
.tote-platform-state.json, .redeem-roundtrip-state.json,
.eurc-onboard-state.json — some contain oracle privkeys / vault
secretKeyBase58; NEVER commit) + the .usdm-historical-chart.html
chart output + MS Office `~$*` lock files + scripts/bundle-surfaces
`build/` output. Also add scripts/bundle-surfaces.mjs.
- CLAUDE.md, WALLET-COORDINATION.md, snapshots/INDEX.md, design/README.md
refreshed.
- package.json / package-lock.json bumps.
Verified: sensitive files at repo root confirmed ignored (git check-ignore
each). No `.env`, no raw WIF/xprv/mnemonic/secretKey/oraclePriv strings in
the staged diff. MS Word autosave file (`Parameters/Philosophy/~$*.docx`)
excluded and gitignored.
The WizardConnect responder work landed separately in the previous commit
(6987591); this is everything else that had accumulated alongside it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
95 lines
5 KiB
Text
95 lines
5 KiB
Text
pragma cashscript ^0.12.0;
|
|
|
|
// DeviantOpenMintNBA — permissionless draw-from-reservoir for a NON-BACKED
|
|
// CashTokens FT category (the NBA family, V2.7 §2.4 — PTU / PTL).
|
|
//
|
|
// Sibling to DeviantOpenMintFT, and the difference is the entire point:
|
|
//
|
|
// DeviantOpenMintFT (MBA/DEA): output[1].value == tokenAmount * backingRate
|
|
// The BCH the claimer pays is LOCKED INSIDE the token UTXO. Redemption is
|
|
// a plain P2PKH spend of that UTXO — the peg is the coin itself.
|
|
//
|
|
// DeviantOpenMintNBA (NBA): output[1].value >= UNIT_DUST (no rate at all)
|
|
// The BCH the drawer pays is PAID AWAY to the founder. Nothing is locked,
|
|
// nothing is redeemable, there is no protocol floor. Value is market-set.
|
|
//
|
|
// So this covenant does not "back" anything; it only decides WHO may take units
|
|
// out of the reservoir and ON WHAT TERMS. That is exactly what the NBA
|
|
// permissionless-mint axis means.
|
|
//
|
|
// RESERVOIR MODEL (inherited, and unavoidable):
|
|
// CashTokens fixes fungible supply at genesis — no transaction can ever
|
|
// increase a category's FT supply, and a minting NFT creates only new NFTs.
|
|
// So "mint" is always a transfer from a genesis-minted reservoir, and the
|
|
// genesis amount IS the hard cap. See ADR-0054: for fungible NBAs, "limited"
|
|
// means a published, economically meaningful cap and "unlimited" means a
|
|
// reservoir sized so the cap never binds. Neither is a mint capability.
|
|
//
|
|
// The two knobs that separate a faucet from a mineable coin:
|
|
// pricePerUnitSats — 0 makes it a free tap (PTU / game currency, faucet);
|
|
// > 0 makes extraction cost real BCH (PTL / "mined by
|
|
// anyone" — finite, unbacked, costly to acquire).
|
|
// cooldownBlocks — relative-age gate on the reservoir UTXO. Because every
|
|
// draw re-creates the reservoir, this rate-limits the
|
|
// WHOLE reservoir to one draw per N blocks — the only
|
|
// thing that keeps a free tap from being emptied in one
|
|
// transaction. 0 disables it.
|
|
// maxUnitsPerDraw — per-transaction ceiling (anti-drain, always on).
|
|
//
|
|
// Output layout (draw):
|
|
// [0] reservoir back to this contract: minting NFT + (remaining FT), >= dust
|
|
// [1] FT to recipient at dust value — NOT backed
|
|
// [2] price to founder, if pricePerUnitSats > 0
|
|
// [3+] BCH change (unconstrained)
|
|
//
|
|
// Category byte order: same as DeviantOpenMintFT — the constructor takes the
|
|
// bare 32-byte category id in CashTokens consensus (little-endian) order.
|
|
|
|
contract DeviantOpenMintNBA(
|
|
bytes tokenCategory, // bare 32-byte category id == genesis TXID (LE)
|
|
int pricePerUnitSats, // 0 = free faucet; > 0 = pay-to-extract
|
|
int maxUnitsPerDraw, // per-tx ceiling, must be > 0
|
|
int cooldownBlocks, // 0 = no rate limit; else reservoir min age
|
|
bytes founderLockingBytecode // 25-byte P2PKH bytecode of the price recipient
|
|
) {
|
|
// draw() — permissionless transfer-from-reservoir, unbacked.
|
|
function draw(int tokenAmount, bytes recipientLockingBytecode) {
|
|
require(tokenAmount > 0);
|
|
require(tokenAmount <= maxUnitsPerDraw);
|
|
|
|
// Rate limit. Guarded so the default (0) costs no sequence-number
|
|
// constraint on the spending transaction.
|
|
if (cooldownBlocks > 0) {
|
|
require(this.age >= cooldownBlocks);
|
|
}
|
|
|
|
int costSats = tokenAmount * pricePerUnitSats;
|
|
|
|
// [0] reservoir back to this contract — same script, same category
|
|
// (preserving the minting NFT capability), FT reduced by exactly the
|
|
// amount that appears in [1].
|
|
require(tx.outputs[0].lockingBytecode == tx.inputs[this.activeInputIndex].lockingBytecode);
|
|
require(tx.outputs[0].tokenCategory == tx.inputs[this.activeInputIndex].tokenCategory);
|
|
require(tx.outputs[0].tokenAmount == tx.inputs[this.activeInputIndex].tokenAmount - tokenAmount);
|
|
require(tx.outputs[0].value >= 546);
|
|
|
|
// [1] FT to the recipient. Dust-valued: no rate, no backing, no floor.
|
|
// The absence of a `value == tokenAmount * rate` constraint here is the
|
|
// structural statement that this asset carries no peg.
|
|
require(tx.outputs[1].lockingBytecode == recipientLockingBytecode);
|
|
require(tx.outputs[1].tokenCategory == tokenCategory);
|
|
require(tx.outputs[1].tokenAmount == tokenAmount);
|
|
require(tx.outputs[1].value >= 546);
|
|
|
|
// [2] Price to the founder — only constrained when non-zero, so a free
|
|
// tap leaves index 2 onward unrestricted (change, etc.).
|
|
if (costSats > 0) {
|
|
// Anti-dust: rounding noise must not produce non-standard outputs.
|
|
// The off-chain planner mirrors this as a minimum viable draw.
|
|
require(costSats >= 546);
|
|
require(tx.outputs[2].lockingBytecode == founderLockingBytecode);
|
|
require(tx.outputs[2].value == costSats);
|
|
require(tx.outputs[2].tokenCategory == 0x);
|
|
}
|
|
}
|
|
}
|