Skip to content
TonyolumidePublic

About

Trusted group savings, contribution tracking, and fiat/onchain settlement platform

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

The Circle

The Circle is a trust-minimized rotating savings protocol for fixed groups. Members agree on a contribution, schedule, and payout order; a smart contract collects each round and pays the scheduled recipient — no organizer holds the pot, and no organizer can disappear with it.

This is pre-audit, testnet-only code. Nothing here should custody real funds yet.

Local development

pnpm install
pnpm test           # contract tests (Hardhat)
pnpm web:dev         # web app (apps/web)
pnpm web:check       # typecheck + lint the web app

What's built, in order

Batch 1: protocol core

The smallest complete on-chain cycle: fixed membership and payout order, one ERC-20 contribution token (intended to be USDC), refundable position-sensitive security deposits, activation only once every member has funded, permissionless round processing after each deadline, allowance-based contribution pulls, automatic deposit coverage for missed contributions, automatic payout to the scheduled recipient, public events and missed-payment counts, unused-deposit withdrawal after completion, and safe pre-activation cancellation. The factory discovers deployed circles but never gains the power to move or redirect member funds.

Batch 2: fiat-first web MVP

The Next.js app in apps/web layers a savings dashboard, circle creation and invitations, bank transfer / debit card / mobile money / wallet contribution choices, local-currency quotes and fee disclosure, sandbox bank-transfer instructions, provider-neutral quote and payment-session APIs, and a signed webhook boundary. Fiat APIs run on a demo provider only — see docs/fiat-architecture.md.

Batch 3: guided account and settlement sandbox

Four-step guided onboarding, a cookie-scoped demo account, activity/notifications/settings/help routes, an idempotent settlement state machine, simulated sponsored-transaction requests, and guarded GIWA Sepolia deployment configuration. See docs/batch-3-architecture.md.

Batch 4: adoption and trust-status layer

A path from an existing offline group to a protected payment product: guided creation and import, explicit Tracker (off-platform money movement, tracked in-app) and Protected (on-platform settlement) circle modes, reported / confirmed / verified trust states per member, payout calendars, reminder previews, invitation links with scannable QR codes, and rule-preview joining. See docs/batch-4-adoption-layer.md.

Batch 5: GIWA Sepolia receipts

The first real on-chain boundary, while payment funds stayed simulated: a non-custodial CircleContributionRegistry contract recording one-time hashed settlement proofs (amount and currency public; no personal or banking data), an authorized-writer allowlist, a chain-ID-guarded deployment script, and confirmed block/explorer receipts in the UI. See docs/batch-5-giwa-testnet.md.

Batch 6: durable hosted sandbox

The web app runs as a Vinext Cloudflare Worker with a Sites-managed D1 database, so sandbox accounts, wallet balances, circles, settlements, and notifications survive worker restarts. /api/health reports readyForRealMoney: false — this is durable demo storage, not a production ledger. See docs/batch-6-production-foundation.md.

Batch 7: prepaid savings vault

SavingsVault lets a member preload the circle token ahead of time and withdraw any unused balance whenever they like. A vault-enabled circle draws from that saved balance first when a round is due, then falls back to the member's direct wallet allowance, then to their security deposit — so a member no longer needs to hold exact liquidity or remember an approval on the due date. Only circles created by the vault's configured factory can pull from it, and the factory rejects a vault built for a different token or a different factory. The authenticated /wallet page provides connection, network switching, live balances, deposits, and withdrawals. See docs/batch-7-savings-vault.md.

Batch 8: protected-circle lifecycle (sandbox)

New circles use one clear Protected standard: once every member has made the current contribution, the sandbox pays the scheduled recipient and opens the next round, and on the last round it returns every unused security deposit, marks the payout calendar complete, and adds a 2% completion reward from a simulated reward pool. The 2% is a sandbox incentive, not investment yield or a promise of return. Run its lifecycle and rendered-worker smoke tests with pnpm --dir apps/web test.

Batch 9: position-based protocol fee

The protocol takes a fee on payout, set once at factory deployment and inherited by every circle — no circle creator can configure their own rate. The fee isn't flat: it's highest for the first payout slot (an effective interest-free advance from everyone paid later) and declines linearly to zero for the last slot (pure saving, nothing advanced), mirroring the fee shape used by MoneyFellows, the largest ROSCA-style fintech operating at real scale. Capped at 5% for the first slot, enforced at deployment. Two view functions, currentPotPreview() and previewFeeForRound(), let the UI disclose the whole fee schedule before a member joins. See docs/batch-9-protocol-fee.md.

Batch 10: payout protection foundation

Protected circles now disclose whether they are Member Protected or Payout Guaranteed. Member Protected circles use refundable member deposits and pause before an uncovered payout; they do not imply that The Circle guarantees the pot. The sandbox also models reserved coverage, idempotent protection claims, recovery-due records, coverage exhaustion, and release after completion. Reserve transfers remain simulated until a real guarantor, ring-fenced accounting, underwriting, claims operations, and regulatory model exist. See docs/batch-10-payout-protection.md.

Batch 11: double-entry ledger foundation

Every sandbox money movement now posts an immutable, balanced journal transaction. Wallet balances are derived projections rather than financial truth; security deposits, round pots, provider clearing, payouts, reward budgets, and protection capital use separate accounts. The ledger supports multi-currency balancing, idempotency, holds, reversals, reconciliation records, and a production Postgres schema with database-enforced invariants. This remains a sandbox foundation, not permission to accept real funds. See docs/batch-11-ledger-foundation.md.

Batch 12: position-sensitive protection funding

Refundable deposits now follow payout risk: the earliest 20% of positions fund three contributions, the middle positions fund two, and the final 20% fund one. Protected circles cannot activate until every exact member deposit is funded; reserve-backed circles must also reserve at least one complete round of coverage. Protocol fees, reward budgets, and reserved protection capital are classified as separate ledger funds, with application and database checks preventing them from being mixed. See docs/batch-12-position-sensitive-protection.md.

Batch 13: operating core, verified reputation, and repeat growth

The production model adds controlled account recovery, recurring-payment mandates, support and incident queues, evidence-based reputation with provenance and correction rights, and event-based repeat/referral attribution. Profiles show promptness only when enough evidence exists and never present savings history as a credit score. The operating policy defines default-risk ownership, ring-fenced reserve capital, earned early-slot review, and the regulated partners required before handling real money. See docs/batch-13-operating-core-reputation-and-growth.md.

Batch 14: PostgreSQL cutover foundation

The Worker can now run in explicit off, shadow, or authoritative PostgreSQL modes using a direct development connection or Cloudflare Hyperdrive. Shadow mode dual-writes versioned JSONB checkpoints and reconciliation evidence while D1 remains authoritative. Authoritative mode reads and commits PostgreSQL and fails closed instead of falling back to a second financial truth. Transaction-scoped locks, fencing versions, database-side checksums, and an idempotent outbox support a controlled projection into the normalized production tables. See docs/batch-14-postgres-cutover.md.

Direct wallet protocol bridge

The Crypto wallet payment option bypasses the fiat sandbox entirely and talks directly to a deployed SavingsCircle through an injected browser wallet: it reads live membership and round state, switches to GIWA Sepolia, approves one fixed cycle of token spending, calls fundDeposit() from the member's own wallet, and exposes permissionless processRound() when a round is due. No server signer or relayer participates in these calls. See docs/wallet-protocol-bridge.md.

Deploying to GIWA Sepolia

pnpm deploy:giwa

Deploys MockUSDC, SavingsCircleFactory (with the fee policy from GIWA_TREASURY_ADDRESS / GIWA_PROTOCOL_MAX_FEE_BPS), SavingsVault, and CircleContributionRegistry. Set GIWA_CIRCLE_MEMBERS to also deploy a wallet-funded test circle and mint test MockUSDC to each member. Copy the printed NEXT_PUBLIC_GIWA_* addresses into apps/web/.env.local. See .env.example for every variable this reads.

Explicit limitations

  • Position-sensitive member deposits cover one to three missed contributions depending on payout position; the next uncovered miss stops that round until funding is restored.
  • Nothing executes itself on a schedule — a keeper, relayer, app backend, or any caller must trigger a due round.
  • Membership, payout order, and the fee policy cannot change after a circle (or factory) is deployed.
  • There is no identity, Sybil resistance, private transaction data, dispute process, lending, yield, upgrade mechanism, or emergency governance.
  • The protocol is non-custodial by design: funds move circle-to-recipient directly, never sitting in a company-held account. That's a deliberate trust trade-off — it also means there's no float income available to the protocol the way a centralized competitor might earn one.
  • A public chain exposes member addresses, contribution amounts, payout order, and payment behavior.

Batch docs

Each batch has a corresponding doc under docs/ with its trust boundary, state model, and production-replacement plan in detail: batch-3-architecture.md, batch-4-adoption-layer.md, batch-5-giwa-testnet.md, batch-6-production-foundation.md, batch-7-savings-vault.md, batch-9-protocol-fee.md, batch-10-payout-protection.md, batch-11-ledger-foundation.md, batch-12-position-sensitive-protection.md, batch-13-operating-core-reputation-and-growth.md, batch-14-postgres-cutover.md, fiat-architecture.md, and wallet-protocol-bridge.md.

About

Trusted group savings, contribution tracking, and fiat/onchain settlement platform

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages