Skip to content

theyavuzarslan/shadow-raise

Repository files navigation

ShadowRaise — Confidential Crowdfunding with a TokenOps Distribution Lifecycle

Zama Developer Program Mainnet Season 3 — Special Bounty Track × TokenOps.

A crowdfunding dApp where every amount is encrypted end-to-end on-chain: contributions arrive as real ERC-7984 confidential-token transfers (TokenOps CTTT on Sepolia), the funding goal itself is a ciphertext, settlement publicly reveals exactly one bit (goal reached or not), and the entire post-raise distribution runs on the TokenOps SDK — founder vesting, confidential team payouts, and encrypted backer rewards.

Distribution Studio

The confidential distribution flow is a first-class, public page — no login, no gating: https://shadowraise-fhe.vercel.app/distribute

  • Confidential Disperse — push encrypted payouts to many recipients in one transaction (team payroll, investor distributions).
  • Confidential Airdrop — fund a claim campaign and hand each recipient a private, per-address claim link. Recipients claim and decrypt their own allocation at /claim.
  • Inline faucet, live validation, bulk paste, and a step indicator so a first-time visitor goes from zero to distributing on one screen.

The crowdfund below is the real-world product built on that same engine.

Two campaign modes, one contract

Two campaign modes, one contract:

  • Business raise (all-or-nothing): funds escrowed; goal missed → trustless encrypted refunds; goal met → owner withdraws and distributes via TokenOps.
  • Donation drive (keep-what-you-raise): withdraw anytime, refunds disabled, the encrypted goal is a private milestone and the campaign never fails. Donate to sensitive causes — medical funds, activism, journalism — without a public donor ledger.

Architecture

                    ┌─────────────────────────────────────────────┐
  backers ──mint──► │ TokenOps testnet faucet (TTT → CTTT)        │
     │              └─────────────────────────────────────────────┘
     │ contribute (ERC-7984 confidential transferFrom, euint64)
     ▼
┌──────────────────────────────┐   settle: FHE.ge(total, goal) →
│ ConfidentialCrowdfund.sol    │   makePubliclyDecryptable(1 bit) →
│  • encrypted goal + total    │   KMS proof checked on-chain
│  • per-backer encrypted      │
│    ledger                    │──failed──► refund(): exact encrypted
│  • auditor selective         │            amount back, trustless
│    disclosure (FHE ACL)      │
└──────────────┬───────────────┘
               │ succeeded → withdraw() (confidential transfer to owner)
               ▼
┌─────────────────────────────────────────────────────────────────┐
│                    TokenOps SDK distribution                    │
│  fhe-vesting: founder funds vest (30-day cliff = rug shield)    │
│  fhe-disperse: confidential bulk payouts to team/providers      │
│  fhe-airdrop: EIP-712-gated encrypted reward claims for backers │
└─────────────────────────────────────────────────────────────────┘

What stays private

Data Visibility
Individual contribution amounts Encrypted (euint64); contributor + campaign owner only
Running total raised Encrypted; owner + granted auditors only
Funding goal Encrypted from deployment; never public
Goal reached? The only public bit, revealed by KMS-proof-checked finalize()
Refund amounts Encrypted confidential transfers
Vesting / payout / reward amounts Encrypted via TokenOps contracts (ERC-7984)
Auditor view grantAuditorAccess() = FHE ACL grant — compliance without disclosure

Repo layout

  • contracts/ConfidentialCrowdfund.sol — escrow + lifecycle (Active → Finalizing → Succeeded/Failed)
  • contracts/test/TestConfidentialToken.sol — local ERC-7984 mock (stands in for CTTT)
  • test/ConfidentialCrowdfund.test.ts — 11 fhEVM-mock tests covering the full lifecycle
  • scripts/deploy.ts — Sepolia deploy against TokenOps CTTT
  • frontend/ — Next.js + wagmi + @zama-fhe/react-sdk + @tokenops/sdk dApp

Key mechanics

  • Real escrow: contribute() pulls CTTT via confidentialTransferFrom (operator flow) and credits the actually transferred ciphertext returned by the token — ERC-7984 transfers are all-or-nothing on ciphertext, so a broke caller cannot inflate the ledger.
  • One-bit settlement: requestFinalize() computes FHE.ge(totalRaised, goal) on ciphertext and marks that single ebool publicly decryptable; finalize() verifies the KMS decryption proof on-chain via FHE.checkSignatures before flipping state.
  • Trustless refunds: on failure, refund() transfers each backer's exact encrypted contribution back — no owner involvement.
  • TokenOps distribution: the owner console drives fhe-vesting, fhe-disperse, and fhe-airdrop (all pre-deployed TokenOps contracts on Sepolia) through the SDK's React hooks; reward allocations are encrypted client-side and bound per-recipient with EIP-712 claim authorizations.

Run it

# contracts
npm install
npx hardhat test                                   # 11 passing on the fhEVM mock

# deploy (Sepolia)
cp .env.example .env                               # PRIVATE_KEY + SEPOLIA_RPC_URL
GOAL_CTTT=1000 DURATION_DAYS=7 npx hardhat run scripts/deploy.ts --network sepolia

# frontend
cd frontend
cp .env.example .env.local                         # set NEXT_PUBLIC_CROWDFUND_ADDRESS
npm install
npm run dev

Stack

  • @fhevm/solidity 0.11 + @openzeppelin/confidential-contracts 0.5 (ERC-7984)
  • @tokenops/sdk 1.1 (fhe-vesting, fhe-disperse, fhe-airdrop, testnet-faucet)
  • @zama-fhe/sdk + @zama-fhe/react-sdk 3.0 (RelayerWeb encryption, user/public decrypt)
  • Hardhat + @fhevm/hardhat-plugin 0.4 (mock coprocessor + KMS-proof testing)
  • Next.js 15 + wagmi v2

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors