Stake DCC. Receive stDCC. Earn rewards. Stay liquid.
stDCC is a liquid staking protocol for DecentralChain — a Waves-derived Layer-1 blockchain using Leased Proof-of-Stake (LPoS).
Users deposit DCC and receive stDCC, a yield-bearing token that appreciates in value as staking rewards accrue. Unlike rebasing tokens, your stDCC balance never changes — its value grows.
┌──────────┐ ┌──────────────────┐ ┌──────────┐
│ │ Deposit │ │ Lease │ │
│ User │ ───DCC──►│ stDCC Protocol │ ────────► │Validators│
│ │ ◄─stDCC──│ (RIDE dApp) │ ◄─rewards─│ │
│ │ │ │ │ │
└──────────┘ └──────────────────┘ └──────────┘
│
stDCC value goes up 📈
Exchange Rate Model — not rebasing.
1 stDCCis always worth ≥1 DCC, and the rate only goes up.
|
|
┌─────────────────────────────────────────────┐
│ DecentralChain L1 │
│ ┌───────────────────────────────────────┐ │
│ │ liquid_staking.ride (dApp) │ │
│ │ │ │
│ │ deposit · withdraw · claim · rewards │ │
│ │ validators · leasing · emergency │ │
│ └───────────────────────────────────────┘ │
└──────────┬──────────┬──────────┬────────────┘
│ │ │
┌───────────────┘ │ └───────────────┐
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ SDK │ │ Indexer │ │ Operator │
│ │ │ │ │ │
│ types │ │ PostgreSQL │ │ sync-rewards│
│ math │ │ REST API │ │ rebalance │
│ tx-builder │ │ poller │ │ finalize │
│ reader │ │ │ │ safety │
└──────┬──────┘ └──────┬───────┘ └──────────────┘
│ │
▼ ▼
┌────────────────────────────────────┐
│ Frontend (Next.js 14) │
│ Tailwind · DCC Keeper · Hooks │
└────────────────────────────────────┘
| Package | Path | What it does |
|---|---|---|
| RIDE Contract | contracts/ride/ |
On-chain dApp — deposit, withdraw, lease, emergency mode |
| SDK | packages/sdk/ |
TypeScript library — bigint math, node client, tx builder |
| Config | packages/config/ |
Shared constants, state key builders, network configs |
| Indexer | apps/indexer/ |
Chain watcher → PostgreSQL → Express REST API |
| Operator | apps/operator/ |
Daemon — rewards sync, lease rebalancing, safety checks |
| Frontend | apps/web/ |
Next.js 14 + Tailwind — stake, unstake, admin panel |
|
Full analysis: Threat Model · Invariants · Incident Runbook
shares_minted = deposit_amount × total_shares ÷ total_pooled_dcc (round ↓)
dcc_redeemed = shares_burned × total_pooled_dcc ÷ total_shares (round ↓)
- Your stDCC balance stays constant — no confusing rebases
- The value per stDCC increases as validators earn rewards
- Rate can never decrease (enforced by invariant + emergency shutdown)
- All math uses BigInt with 8-decimal precision (1 DCC = 100,000,000 wavelets)
| Tool | Version |
|---|---|
| Node.js | ≥ 18 |
| npm | ≥ 9 (workspaces) |
| PostgreSQL | ≥ 14 (indexer) |
git clone https://github.com/dylanpersonguy/dcc-staking.git
cd dcc-staking
npm install
cp .env.example .env # configure your environment
npm run build # build all packages# 1. Start the indexer (chain watcher + API)
cd apps/indexer && npx ts-node src/index.ts
# 2. Start the operator daemon
cd apps/operator && npx ts-node src/index.ts
# 3. Start the frontend
cd apps/web && npm run dev
# → http://localhost:3000# Deploy contract to testnet
npx ts-node scripts/deploy.ts --network=testnet
# Seed test data
npx ts-node scripts/seed.ts
# Run smoke tests against live deployment
npx ts-node scripts/smoke-test.ts
# Run unit tests
npm testdcc-staking/
│
├── contracts/ride/
│ └── liquid_staking.ride # RIDE v6 smart contract (~500 lines)
│
├── packages/
│ ├── config/src/
│ │ ├── constants.ts # Protocol constants & state key builders
│ │ └── networks.ts # Testnet / mainnet configuration
│ │
│ └── sdk/
│ ├── src/
│ │ ├── types.ts # TypeScript interfaces & enums
│ │ ├── math.ts # BigInt exchange rate arithmetic
│ │ ├── node-client.ts # DecentralChain node REST wrapper
│ │ ├── protocol-reader.ts # Read on-chain protocol state
│ │ ├── tx-builder.ts # Build InvokeScript transaction params
│ │ └── parser.ts # Parse data entries into typed events
│ └── __tests__/ # Unit tests (math, builder, parser)
│
├── apps/
│ ├── indexer/src/ # Chain watcher + PostgreSQL + REST API
│ ├── operator/src/ # Automated daemon (rewards, leasing, safety)
│ └── web/src/ # Next.js 14 frontend (stake/unstake UI)
│
├── scripts/
│ ├── deploy.ts # Contract compilation & deployment
│ ├── seed.ts # Test data seeding
│ └── smoke-test.ts # End-to-end protocol verification
│
├── docs/
│ ├── architecture.md # System design & component diagram
│ ├── state-schema.md # On-chain data key specifications
│ ├── threat-model.md # 13-threat security analysis
│ ├── invariants.md # 10 non-negotiable protocol invariants
│ └── runbook.md # Incident response procedures
│
├── turbo.json # Turborepo pipeline config
├── tsconfig.base.json # Shared TypeScript strict config
└── .env.example # Complete environment template
5,400+ lines of TypeScript & RIDE across 70 files
All settings are controlled via environment variables. See .env.example for the full template.
Key Variables
| Variable | Description | Default |
|---|---|---|
DCC_NODE_URL |
DecentralChain node RPC endpoint | https://testnode1.decentralchain.io |
DCC_CHAIN_ID |
T for testnet, D for mainnet |
T |
DAPP_ADDRESS |
Deployed dApp address | — |
ADMIN_ADDRESS |
Protocol admin address | — |
OPERATOR_SEED |
Operator daemon signing seed | — |
TREASURY_ADDRESS |
Fee collection address | — |
PROTOCOL_FEE_BPS |
Protocol fee (basis points) | 1000 (10%) |
DATABASE_URL |
PostgreSQL connection string | postgresql://localhost:5432/dcc_staking |
INDEXER_PORT |
Indexer REST API port | 4000 |
User calls deposit() with DCC payment
→ Protocol calculates shares: amount × totalShares ÷ totalPooledDcc
→ stDCC minted to user (native asset Issue/Reissue)
→ DCC added to pool, leased to validators
1. User: requestWithdraw(stDCC) → status: "pending"
2. Operator: finalizeWithdraw() → status: "ready" + DCC amount locked
3. User: claimWithdraw(id) → status: "claimed" + DCC transferred
lease_target = total_leasable_dcc × (validator_weight / 10000)
The operator daemon continuously rebalances leases across validators, canceling leases as needed to maintain liquidity for withdrawals.
| Phase | Scope | Status |
|---|---|---|
| Phase 1 | Core deposit/withdraw, multi-validator, manual admin, exchange rate model | ✅ Complete |
| Phase 2 | Guardian role, automated rebalancing, enhanced monitoring, slashing support | 🔧 In Progress |
| Phase 3 | On-chain governance (DAO), DeFi integrations (DEX/lending), insurance pool | 📋 Planned |
npm run build # Build all packages (via Turborepo)
npm run dev # Dev mode with watch
npm run lint # Lint all packages
npm run test # Run all tests- RIDE v6 — Smart contract language for DecentralChain
- TypeScript 5.3 — Strict mode, ES2022 target
- Turborepo — Monorepo orchestration with caching
- Next.js 14 — App Router, Server Components
- Tailwind CSS 3.4 — Utility-first styling with custom
dccpalette - PostgreSQL — Indexer persistence layer
- Express — Indexer REST API
- Jest + ts-jest — Unit testing with TypeScript support
| Document | Description |
|---|---|
| Architecture | System design, transaction flows, component diagram |
| State Schema | Complete on-chain key naming, types, collision analysis |
| Threat Model | 13 attack vectors analyzed with mitigations |
| Invariants | 10 non-negotiable protocol invariants |
| Runbook | Incident response for SEV-1 through SEV-3 events |
Items marked TODO(chain-confirmation) in the codebase require adaptation to the exact DecentralChain transaction signing library. All protocol logic is complete — these TODOs cover only the wire-level transaction format (signing, Lease/LeaseCancel construction, broadcast).
MIT — build on it, fork it, stake with it.
Built for DecentralChain · Exchange Rate Model · Monotonic Rewards · Zero Rug-Pulls