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>
53 lines
2.8 KiB
Text
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);
|
|
}
|
|
}
|