deviant/contracts/EscalatingVoteDualNFT.cash
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

53 lines
2.8 KiB
Text

pragma cashscript ^0.12.0;
// EscalatingVoteDualNFT — anti-plutocracy vote with FIXED redeemable backing and
// a DUAL-escalating, fully non-recoverable cost. Corrects EscalatingDualLadderNFT,
// which (wrongly) locked the escalating rate as recoverable backing.
//
// - REDEEMABLE backing per vote is FIXED at `baseBacking` (e.g. 100,000 sats =
// "1 vote"), always refundable — "nothing more". The rate never inflates it.
// - The rate notional in the NFT commitment escalates x10 (fee-scaling only).
// - fee% escalates in lockstep: feeBps = baseFeeBps * rate / startRate
// -> 1% -> 10% -> 100% -> 1000% ...
// - fee = rate * fee% (compounds ~x100/vote), ALL non-recoverable -> treasury.
// total paid = baseBacking (refundable) + fee (burned).
//
// So accumulating votes is exponentially costly in NON-recoverable terms, while
// every vote keeps the same small refundable stake. NFT returns to the contract
// -> ratchet can't be reset. No pow/loops.
contract EscalatingVoteDualNFT(
bytes tokenCategory,
bytes founderLockingBytecode, // treasury — escalating non-recoverable fee
int startPrice, // unit-1 rate notional (fee-ladder divisor), e.g. 100000
int baseFeeBps, // unit-1 fee bps, e.g. 100 = 1%
int baseBacking // FIXED redeemable sats per vote, e.g. 100000 ("nothing more")
) {
function buy(bytes recipientLockingBytecode) {
int price = int(tx.inputs[this.activeInputIndex].nftCommitment); // rate notional, x10/vote
require(price >= startPrice);
int reservoir = tx.inputs[this.activeInputIndex].tokenAmount;
require(reservoir >= 1);
int feeBps = baseFeeBps * price / startPrice; // 1% -> 10% -> 100% -> ...
int fee = price * feeBps / 10000; // = rate * fee% (non-recoverable)
// [0] position back to THIS contract: rate x10, FT-1, mutable NFT preserved.
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 == reservoir - 1);
require(tx.outputs[0].nftCommitment == bytes(price * 10));
require(tx.outputs[0].value >= 546);
// [1] vote unit to the voter: FIXED redeemable backing, never the rate.
require(tx.outputs[1].lockingBytecode == recipientLockingBytecode);
require(tx.outputs[1].tokenCategory == tokenCategory);
require(tx.outputs[1].tokenAmount == 1);
require(tx.outputs[1].value == baseBacking);
// [2] escalating fee -> treasury (non-recoverable; >= dust by construction).
require(tx.outputs[2].lockingBytecode == founderLockingBytecode);
require(tx.outputs[2].value == fee);
require(tx.outputs[2].tokenCategory == 0x);
}
}