Behavioral-credit infrastructure for Solana. RoundFi runs on-chain ROSCAs as a data-acquisition engine: every paid installment mints an on-chain attestation that builds a portable credit identity. The ROSCA is the bait; the behavioral score is the product. Endgame: a high-margin B2B oracle that neobanks and DeFi protocols subscribe to before lending — the Serasa of Web3.
🚀 Live demo · 🎬 Demo (video) · 🎙️ Pitch (video) · 📋 Status (shipped vs roadmap) · 📊 3-min Pitch (EN) · 📊 3-min Pitch (PT) · 📊 Long-form Deck (EN) · 🧱 Architecture · 🛡️ Audit-Readiness · 📋 Audit Scope · 📦 Grant bundle
Status: M3 shipped · 4 programs live on devnet · reproducible-build attestation on-chain · 162 tests / 53 security-specific · seeking external audit (Adevar Labs track). Last updated: May 2026.
Built for the Colosseum Hackathon 2026.
DeFi solved trading. DeFi solved liquidity. DeFi never solved credit. The two clearest attempts at on-chain ROSCAs / under-collateralized retail credit both shipped — and both went quiet:
- WeTrust (Ethereum, 2017–2018) — first on-chain ROSCA, Trusted Lending Circles. Gas costs ate margins, retention collapsed when ETH stalled, and the protocol was the product — no data layer to monetize. Wound down quietly.
- RociFi (Solana, 2021–2023) — under-collateralized lending with NFT credit scores. The score was program-internal (not portable, not SAS-compatible), B2B distribution never materialized, and liquidator economics broke under volatility. Project sunset.
| Protocol | Status | Sub-collateral | Behavior score | Retail user | Emerging markets | Position NFT | No prior crypto |
|---|---|---|---|---|---|---|---|
| Aave / Marginfi | live | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| Goldfinch | live | ✓ | ✗ | ✗ | ~ | ✗ | ✗ |
| Maple / TrueFi | live | ~ | ✗ | ✗ | ✗ | ✗ | ✗ |
| Credix | live | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ |
| WeTrust | sunset | ✓ | ✗ | ✓ | ~ | ✗ | ✗ |
| RociFi | sunset | ✓ | ~ | ~ | ✗ | ~ | ✗ |
| RoundFi | devnet | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
The boxes alone don't make us right — Aave, Goldfinch, and Credix are real businesses with billions of TVL between them. What separates RoundFi from the projects that sunset is structural, not feature-list:
- Phase 3 is the revenue model from day 1, not an afterthought. WeTrust's protocol was the product, so when retention slipped there was nothing left to sell. RociFi's NFT score didn't read outside their pools, so there was no B2B moat. RoundFi treats Phase 1 (ROSCAs) explicitly as the data-acquisition engine for Phase 3 (per-call B2B oracle subscriptions to neobanks + DeFi protocols). The Triple Shield + Yield Cascade exist to keep Phase 1 solvent while the on-chain dataset compounds.
- Score is SAS-compatible from the first attestation. Every paid installment mints against the Solana Attestation Service schema, so the score reads from any wallet, any protocol — Web3-native portability instead of vendor lock-in. RociFi's score died with RociFi.
- Solvency is mathematical, not aspirational. WeTrust's retention model was "members keep paying because trust." RoundFi's Triple Shield gives a 91.6% Month-1 retention floor as a deterministic property of the contract — encoded in
programs/roundfi-core/src/math/waterfall.rsand parity-tested against the Stress Lab L1 simulator. Stake decays 50% → 30% → 10% but only after on-chain attestations confirm cycle completion — no honor system.
RoundFi is a behavioral-credit primitive disguised as a savings protocol. The product evolves through three explicit phases — codified in the B2B plan and Expansion plan:
| Phase | Surface | What it does |
|---|---|---|
| 1 · Liquidity | ROSCA pools on Solana | Bootstrap users with sub-collateralized credit. Stake ladder 50% → 30% → 10% as reputation graduates. |
| 2 · Reputation | SAS attestations + behavioral score | Every paid installment mints an immutable attestation; the score becomes a portable credit identity. |
| 3 · B2B data | Behavioral oracle API | Neobanks, DeFi protocols, and emerging-market lenders subscribe per-call to query the score before extending credit. High-margin endgame. |
Phase 1 is the acquisition engine. Phase 3 is the business model. The Triple Shield + Yield Cascade exist to keep Phase 1 solvent while the on-chain dataset compounds. Esusu hit a $1.2B valuation building Phase 2 in Web2; RoundFi does it on-chain with deterministic logic, then sells the data layer.
- Pool shape: 24 members · $416/mo installment · ~$10K credit per cycle
- Reputation ladder (50-30-10 Rule): stake drops 50% → 30% → 10% as members graduate Level 1 → 2 → 3 (Veteran). Veterans unlock 10× leverage.
- Triple Shield:
- Seed Draw — Month-1 retention of 91.6% of capital.
- Adaptive Escrow — locks reward portions so debt decreases faster than collateral returns.
- Solidarity Vault — 1% of each installment, redistributed as Good Faith Bonus.
- Yield Waterfall (Kamino, 5–8% APY): Protocol → Guarantee Fund → LP Angels → Participants.
- Escape Valve: positions are dynamic NFTs. Distressed users sell instead of defaulting.
- Behavioral oracle: every payment is an on-chain attestation (SAS-compatible) — a portable credit identity, the "Serasa of Web3".
The protocol's economic spec is encoded in a pure-TypeScript actuarial simulator that runs every Triple-Shield rule end-to-end. Lives in sdk/src/stressLab.ts and ships the /lab interactive route. Used as:
- Reference implementation for the on-chain Anchor programs (M2 of the grant roadmap parity-tests against
runSimulation()outputs). - Whitepaper-faithful playground — pick credit/members/tier/maturity/APY and watch the matrix unfold. 4 canonical presets (Healthy / Pre-default / Post-default / Cascade) load with one click.
- Audit panel with full capital-structure breakdown: float + Solidarity Vault + Guarantee Fund (capped at 150% of credit) − outstanding escrow − outstanding stake refund = Net Solvency. Plus the 4-tier yield waterfall (admin fee → GF → 65% LPs → 35% participants).
40 L1 tests green under pnpm run test:economic-parity-l1 covering: input refactor (credit-amount as primary), toggleCell click semantics, escrow gating on default month, stake cashback phase, net-solvency identity, capital structure invariants, mature-group acceleration (5/4/3 → 3/2/1), Escape Valve "E" cell architecture, and the 4-tier waterfall split.
L1 ↔ L2 parity validated on-chain (Healthy preset). The Healthy matrix from runSimulation() is now driven end-to-end against roundfi-core and asserts per-member USDC delta on-chain ≡ L1 net within ε = 1 USDC base unit. Pre-default / Post-default / Cascade unlock mechanically once the canary turns green organically; the matrix-driver harness already supports all four preset shapes.
RoundFinancial/
├── programs/ # Anchor programs (Rust)
│ ├── roundfi-core/ # Pool state machine + escrow + solidarity vault
│ ├── roundfi-reputation/ # SAS-compatible attestation + reputation ladder
│ ├── roundfi-yield-mock/ # Devnet yield adapter (simulated APY)
│ └── roundfi-yield-kamino/ # Mainnet yield adapter (real Kamino CPI)
├── sdk/ # TypeScript SDK generated from Anchor IDL
├── services/orchestrator/ # Lifecycle orchestrator (mock + real driver)
├── app/ # Next.js 14 front-end (Wallet Adapter, Phantom/Solflare/Backpack)
│ ├── src/app/ # Routes
│ │ ├── page.tsx # / public landing (CoFi paradigm + Security grid + FAQ + Waitlist)
│ │ ├── home/ # /home Bento dashboard (gated by wallet connect)
│ │ ├── carteira/ # /carteira (4 tabs · Receive/Send/Withdraw modals · DEMO badges)
│ │ ├── grupos/ # /grupos catalog (level gating · Novo ciclo modal)
│ │ ├── reputacao/ # /reputacao SAS passport (copyable · Bond detail modal · level-up bridge)
│ │ ├── mercado/ # /mercado Buy + Sell tabs (Escape Valve flow)
│ │ ├── insights/ # /insights score curve (zooming range · Recommendation modals)
│ │ ├── lab/ # /lab Stress Lab (L1 actuarial simulator · 5 preset scenarios)
│ │ └── demo/ # /demo lifecycle demo (orchestrator + wallet adapter)
│ ├── src/components/ # By feature: brand · layout · home · carteira · grupos · score · mercado · lab · insights · modals
│ ├── src/lib/ # Theme · i18n (510+ keys PT/EN) · wallet · network · session · groups helpers
│ ├── src/data/ # Typed mock fixtures (USER, NFT_POSITIONS, ACTIVE_GROUPS, …)
│ └── public/prototype/ # Original design handoff bundle (legacy preview)
├── scripts/ # Devnet deploy, airdrop, seed, stress runners
├── config/ # Cluster configs + program-ID registry
├── tests/ # Cross-program integration tests (Anchor + bankrun)
│ ├── parity.spec.ts # Rust ↔ TS constants/seeds parity (zero infra)
│ ├── economic_parity.spec.ts # L1 ↔ L2 economic parity (40 tests passing)
│ └── *.spec.ts # 17 additional specs · 162 cases total (lifecycle, edge, security, reputation, yield, events)
├── grant/ # Superteam Agentic Engineering grant bundle (7 docs)
└── docs/ # Architecture, module specs, deploy guides
├── pitch/ # 3-min decks (PT + EN) + long-form deck
└── pt/ # Portuguese strategy docs (whitepaper + planning)
Core
- Architecture Spec — programs, accounts, instructions, PDAs, CPI graph, error taxonomy
- Devnet Setup — full prerequisites + deploy walkthrough
- Pitch Alignment — how the implementation maps to the deck
- Yield & Guarantee Fund — waterfall math + adapters
Pitch
- 3-min Pitch · EN — 12-slide short-form deck (English)
- 3-min Pitch · PT — 12-slide short-form deck (Portuguese)
- Long-form Deck · EN — 15-slide Colosseum deck
English (strategy + technical) — full index in docs/en/
- 00 · Documentation Index — formal strategic index of the package
- 01 · Overview — entry point, 60-second pitch in document form
- 02 · Technical Whitepaper — protocol whitepaper, source of truth for mechanics
- 03 · Architecture Spec — program topology, account model, instruction surface
- 04 · Behavioral Reputation Score — 50/30/10 ladder + attestation schemas
- 05 · Stress Lab & Economic Model — L1 actuarial simulator + Triple Shield invariants
- 06 · Market & GTM — market sizing + ICP + go-to-market motion
- 07 · Business Model & B2B Oracle — 3-phase revenue + Phase 3 endgame
- 08 · Competitive Analysis — honest positioning vs Aave, Kamino, Maple, TrueFi, Goldfinch, Credix, RociFi, ARCx, WeTrust
- 09 · Risk & Compliance — risk taxonomy + regulatory framing + compliance posture
- 10 · User Guide — end-user onboarding, step by step
- 11 · Devnet Status & Proof — Solscan receipts + Triple Shield enforcement evidence
Grant bundle (Superteam · Agentic Engineering)
- Grant index — 7-file response bundle
- Project overview · Agentic process · PR log
- Grant use · Builder note · Milestones
Portuguese (strategy + research)
- Whitepaper Técnico
- Guia do Usuário
- Viabilidade Técnica
- Escada de Reputação
- Válvula de Escape
- Plano Estratégico B2B
- Plano de Expansão
Per-module READMEs land alongside each module as it ships.
A complete Next.js 14 + TypeScript app with a public landing + 9 routes (/home, /carteira, /grupos, /reputacao, /mercado, /insights, /lab, /admin Demo Studio, /demo), real Solana wallet integration (devnet), session-orchestrated state, and a Web3-native aesthetic system (Neon palette, glassmorphism, animated counters, terminal-style activity log).
🚀 Try it now: roundfinancial.vercel.app — every push to
mainauto-deploys; PRs get preview URLs.
Run locally:
pnpm install
pnpm --filter @roundfi/app dev
# -> http://localhost:3000/| Route | What's there |
|---|---|
/ |
Public landing — animated gradient title + PT/EN toggle + interactive simulator + comparison table + CoFi paradigm + 6-card Security grid + 5-Q FAQ accordion + Waitlist form + scrolling tx-id "data stream" behind the hero. Connect Phantom CTAs redirect to /home. |
/home |
Bento dashboard — clickable KPI cards (Saldo/Yield → /carteira, Colateral → /insights) + featured round with CTAs (Pagar parcela / Ver no catálogo) + clickable group rows (open PayInstallmentModal) + radial SAS Passport ring + Triplo Escudo + live Activity feed. |
/carteira |
4 tabs · 5 wired modals: Receber (QR + copy address), Enviar (base58 validation + MAX), Sacar (Kamino yield withdraw), Gerenciar (per-connection inspector). PhantomFaucet (1-SOL airdrop + hosted fallback + Circle USDC). DEMO badges on Civic/Kamino/Solflare/PIX mocks. WalletChip airdrop has inline pill feedback. |
/grupos |
ROSCA catalog with search + 5 multi-facet filters + level gating in 3 layers (locked card visual + locked-state modal + defensive joinGroup() guard). + Novo ciclo opens NewCycleModal (eligible if Lv.3, locked otherwise). |
/reputacao |
SAS passport — click-to-copy wallet + radial score + 50/30/10 ladder with level-up bridge to /insights + 4 SAS bonds opening BondDetailModal (attestation count, on-chain path, demo callout). |
/mercado |
Buy + Sell tabs · Buy modal (offer summary + savings + demo callout for escape_valve_buy) · Sell modal (price slider 50–100% of face + 7-day slashing window + Whitepaper protections panel). |
/insights |
Score evolution — range pill (1M/3M/6M/12M) that actually reshapes the curve + 5-factor breakdown + 3 clickable recommendation cards opening detail modals (GANHO ESTIMADO / POR QUE / SINAL ON-CHAIN). |
/lab |
Stress Lab — L1 actuarial simulator. Inputs: tier · maturity · members · credit value · APY · admin fee. 4 one-click preset scenarios. Matrix editor (P/C/X/E cells with position-aware toggle). Pool-balance sparkline. Audit panel: Caixa Bruto + Cofre Solidário + Fundo Garantido − obrigações pendentes = Solvência Líquida. |
/demo |
Lifecycle orchestrator demo (developer-facing, not in user nav). |
Calibrated against a "Web3 high-end" brief. The whole dashboard reads as a live system, not a banking statement.
- Neon palette by default —
#06090Fground,#14F195Solana green,#9945FFpurple,#00C8FFteal accent. Soft (cream + sage) palette stays available via the dev Tweaks panel. - Glassmorphism on every primary card —
backdrop-filter: blur(12px) saturate(140%)over a translucent base + 1px hairline border. One helper (glassSurfaceStyle(palette)) drives every screen. - Terminal sidebar — uppercase JetBrains Mono labels with 0.12em tracking, glowing green active rail.
- SOLANA_DEVNET pulse — network status chip in the top bar pulses a green dot when connected;
PHANTOM_OFFLINEgreys out otherwise. - Wallet glow — connected wallet chip runs a subtle
rfi-glowhalo loop; landing CTAs run biggerrfi-btn-glow-green/purplehalos so every Connect button reads as the primary action immediately. - Animated CountUp — every hero number (saldo, yield, score, KPIs) spring-animates between values when currency / language / palette flips.
- Terminal Activity feed — live event stream from the session orchestrator rendered with
>prompt +[timestamp]+ op tag + amount + tx id, color-coded per row kind (in / out / attestation / join / yield). - Bento
/home— asymmetric grid: 3 KPIs + tall radial Score ring + 3-col Featured round + balanced YourGroups / TripleShield + full-width Activity log. - Radial SAS Score ring — 168px SVG arc with green→teal gradient, draws in over 1.6s on first paint.
- Page transitions — selectable via Tweaks panel: off / fade (default) / horizontal slide. Driven by framer-motion +
usePathname.
- Real wallet flow — Standard-wallet discovery via
@solana/wallet-adapter-reactpicks up Phantom / Solflare / Backpack automatically. Connect from the landing → bounces to/home. Disconnect from the wallet chip dropdown → bounces back to/. - Devnet faucet — One-click 1-SOL airdrop inside the Phantom card on
/carteira. Falls back to https://faucet.solana.com when the public RPC rate-limits (always-visible secondary CTA), plus https://faucet.circle.com for devnet USDC. - Functional modals (17) — every actionable surface across the app routes to an honest demo modal:
/home: PayInstallmentModal (Triple Shield breakdown), JoinGroupModal (locked branch when Lv > user.level)/grupos: JoinGroupModal, NewCycleModal (eligible vs locked)/mercado: BuyOfferModal (offer summary + savings), SellPositionModal (slider + Escape Valve panel), SellShareModal (legacy)/carteira: ReceiveModal, SendModal (address validation + MAX), WithdrawYieldModal, ManageConnectionModal/reputacao: BondDetailModal (attestation count + on-chain path)/insights: RecommendationModal (3 detail variants)/lab: MemberInfoModal (per-member ledger drilldown)- All animated via framer-motion, body-scroll locked, Esc + click-outside close. Each one names the M3 Anchor instruction it'll wire to in production via a yellow
MODO DEMOcallout.
- Session orchestrator —
lib/session.tsxdrives a typed reducer over{ user, events[] }. Submitting a modal really mutates balance / score / yield. An ambient yield ticker fires every 35s so the dashboard reads as alive even while idle. - i18n PT/EN — Every label, button, message, and the entire landing flip on a single toggle. 650+ keys per locale (~1,300 total) in
lib/i18n.tsx. - BRL ↔ USDC currency toggle — Source data is BRL;
fmtMoney(brl)converts at runtime (USDC_RATE = 5.5).
RFILogoMark— pure SVG vector, gradient#27D67B → #3BC6D9 → #1E90C9. Same component drives the landing header, footer, and the/icon.svgfavicon (both are vectorized — no raster fallbacks).- Brand kit —
RFIPill× 6 tones,RFICard× 4 accents,MonoLabel, 26 stroke-based icons incomponents/brand/. - Typography — Syne (display, 400–800), DM Sans (body, 400–700), JetBrains Mono (numbers, 400–600). Loaded via
next/font/googleand exposed as CSS variables.
- Tweaks panel (bottom-right ✨ button, dev/preview only) — flip palette, page-transition mode, and quick-jump between routes. Hidden in production.
- Typed mock data —
data/{carteira,groups,score,market,insights}.tswith full types so screens are self-contained until the on-chain indexer ships.
186 PRs merged on main · all squash-merged via claude/<scope> branches with structured bodies + Claude session links.
| Step | Status |
|---|---|
| 1. Project analysis | ✅ Done |
| 2. Architecture spec | ✅ Done |
| 3. Devnet environment | ✅ Done |
| 4. Smart contracts drafted | ✅ ~6,150 LoC across 20 roundfi-core instructions (lifecycle: create_pool, init_pool_vaults, join_pool, contribute, claim_payout, release_escrow, settle_default, escape_valve_list/buy, close_pool; yield: deposit_idle_to_yield, harvest_yield; governance: initialize_protocol, update_protocol_config, propose/cancel/commit/lock_treasury, pause; dev: ping) + math modules + state types. Validated end-to-end on devnet across M1, M2, M3 (see row 10). 1 protocol fix shipped during M3 (mpl-core owner-managed plugin re-approval after TransferV1). |
| 5. Contract tests | 🟢 L1↔L2 economic-parity scaffold + 162 test cases across 18 spec files covering lifecycle, edge cases (cycle boundaries, degenerate shapes, grace-period defaults, shield-1-only seizure), security (CPI, inputs, audit paths, economic invariants, lifecycle), reputation (guards, CPI, lifecycle), yield integration, parity, and event encoding. All passing under bankrun + the same IDL-free SDK encoders the front-end and indexer use. |
| 6. Backend services | 🟢 SDK + indexer scaffold shipped, browser round-trip closed. @roundfi/sdk ships 7 IDL-free TS action helpers (initializeProtocol, createPool, joinPool, contribute, claimPayout, settleDefault, closePool in actions.ts) + 3 raw account decoders (Pool, Member, Listing in onchain-raw.ts) + event encoders (events.ts) + PDA derivation helpers (pda.ts), consumed by both the front-end and the indexer. services/indexer/ ships Fastify + Helius webhook + Prisma/Postgres schema (pools/members/attestations) + getProgramAccounts backfill. Round-trip proven end-to-end: PayInstallmentModal → SDK encoder → Phantom signs → devnet → Solscan tx 37FZUtg7…wg6f; ClaimPayoutModal → tx LKickMQ1…SEv7Ym. Pending: reconciler that joins event rows → canonical pool/member rows + B2B score oracle endpoint + indexer running on a hosted cluster (post-hackathon). |
| 7. Frontend | ✅ Landing + 9 routes (/home, /carteira, /grupos, /reputacao, /mercado, /insights, /lab, /admin Demo Studio, /demo) + Phantom devnet flow + 17 functional modals + Stress Lab L1 reference + Web3 aesthetic system + 6 Demo Studio presets with deterministic clean-stage iteration (synthesizes implied payment history so /insights factors and Activity feed reflect persona, no residual state between preset loads) |
| 8. Integration | 🟢 End-to-end browser → SDK → devnet round-trip closed. Phantom-signed contribute() + claim_payout() from PayInstallmentModal/ClaimPayoutModal route through @roundfi/sdk (IDL-free encoders) to devnet RPC and surface receipts in Solscan. The Receber CTA covers all three group surfaces: FeaturedGroup, GroupRow, and /grupos GroupCard, plus the Demo Studio mock-mode path. /insights factors reactive to live session state (events + joinedGroups). Pending: indexer-backed reads (front-end reads on-chain directly today; B2B oracle endpoint and reconciler are post-hackathon). |
| 9. Security audit | 🟡 Internal audit shipped (docs/security/self-audit.md) covering threat model, asset/trust model, the Triple Shield invariants (seed-draw, GF solvency, D/C invariant) with file:line references, all 10 PDA seed conventions, per-instruction privilege table for all 20 ix, 53 security-specific test cases mapped to each invariant, and the mpl-core TransferV1 plugin-authority bug surfaced + fixed during M3 devnet exercising. Automated tooling (cargo audit, anchor build, parity tests) runs in CI. SECURITY.md published for responsible disclosure. External third-party audit (Halborn/Ottersec/Sec3) + bug bounty deferred to mainnet migration phase — out of hackathon scope. |
| 10. Devnet testing | 🟢 Full M3 protocol surface exercised on devnet across three pools + Escape Valve + Pool 1 finalized via close_pool (balanced summary: total_contributed=$90 = total_paid_out=$90) + Pool 3 settle_default with Triple Shield seizure on real funds. Pool 1: 3-cycle ROSCA closed + EscrowLocked negative test + close_pool. Pool 2 (cycle_duration=3600s): ON-TIME contribs + Yield Cascade + positive release_escrow + escape_valve_list + escape_valve_buy. Pool 3 (cycle_duration=60s, GRACE_PERIOD=60s devnet patch): fresh wallet set joined, slot 2 fell behind ($5 < $10 installment), claim_payout(0) advanced the cycle, settle_default(1) drained the solidarity vault ($0.20) and stopped at shield 1 because the D/C invariant already held — member.defaulted=true, SCHEMA_DEFAULT attestation written, escrow + stake left intact. Real mpl-core bug surfaced and fixed end-to-end: TransferV1 resets owner-managed plugin authorities; fix re-approves them post-transfer. 4 Triple Shield guards captured firing on real funds (WaterfallUnderflow ×2, EscrowLocked, shield-1-only seizure). Browser-signed write loop closed end-to-end: member-3 contributes via PayInstallmentModal → tx 37FZUtg7…wg6f; member-4 receives via the new ClaimPayoutModal → tx LKickMQ1…SEv7Ym. The Receber CTA also extends to Demo Studio mock mode + /grupos GroupCard so cenários sem wallet real (Maria contemplada, etc.) drivem o mesmo modal com session reducer — same protocol economics surfaced live (PROGRESSO DE PAGAMENTO + TRIPLE SHIELD GARANTIA blocks). Phase 3 indexer scaffold also landed (Fastify + Helius webhook + Postgres event store via Prisma + getProgramAccounts backfill — wired against the same IDL-free SDK decoders the front-end uses). 10 Solana 3.x Box workarounds + 1 protocol fix shipped. See docs/devnet-deployment.md. |
| 11. Mainnet migration | ⏳ |
The post-deploy register lives at docs/devnet-deployment.md — that's where program IDs, tx signatures, deployer keypair, and the verification checklist are recorded. The tables below mirror the headline IDs so reviewers can hop straight to Solscan from the README.
Status:
_FILL_ME_placeholders below are intentional — they get filled in the same commit as the actual deploy, so the register exists pre-deploy and the diff is auditable in one PR.
| Program | Program ID | Status | Solscan |
|---|---|---|---|
roundfi-core |
8LVrgxKwKwqjcdq7rUUwWY2zPNk8anpo2JsaR9jTQQjw |
✅ deployed · 🔐 attested | view |
roundfi-reputation |
Hpo174C6JTCfiZ6r8VYVQdKxo3LBHaJmMbkgrEkxe9R2 |
✅ deployed · 🔐 attested | view |
roundfi-yield-kamino |
74izMa4WzLuHvtzDLdNzcyygKe5fYwtD95EiWMuzhFdb |
✅ deployed · 🔐 attested | view |
roundfi-yield-mock |
GPTMPgxexhwkhXNovnfrcSsmoWPUhedvKAQfTV2Ef5AQ |
✅ deployed · 🔐 attested | view |
🔐 Reproducible build, attested on-chain. Every byte at the program addresses above is bound to commit
5f1673bof this repo via an OtterSec verify-build attestation PDA on devnet. Bytecode is reproducible from source: rebuilding inside the officialsolanafoundation/solana-verifiable-build:1.18.26Docker image produces a.sowhose hash matches the deployed program account. Audit yourself in 30 seconds:solana-verify -u https://api.devnet.solana.com get-program-pda \ --program-id 8LVrgxKwKwqjcdq7rUUwWY2zPNk8anpo2JsaR9jTQQjw \ --signer 64XM177Vm6zirzQnjU1juQ9TLqDsZVsCcZzfgEgVCffmReturns the bound
git_url+commit+executable_hash. Compare againstsolana-verify -u devnet get-program-hash <pid>(deployed bytecode) andsolana-verify get-executable-hash target/deploy/<prog>.so(your local rebuild) — all three match. Full flow including the Docker build + redeploy step:docs/verified-build.md.The green "Verified Build" tile on Solscan is gated on OtterSec's remote build queue, which is mainnet-only by design — out of scope while RoundFi runs on devnet. The on-chain attestation here gives the same hash-binding guarantee, just CLI-checked instead of UI-rendered.
Initialize + seed txs:
-
initialize_protocol→3gCY7M…fXNUz· ProtocolConfig PDA =3c9MmoM…vJoTMV -
initialize_reputation→59Sgz1…ALCn1· ReputationConfig PDA =7RDWsSDc…aXo4 -
create_pool→2Emh1s…E8urS· Pool PDA =5APoECXz…c8ooa(demo, 3 members, $30 carta, 3 cycles) -
init_pool_vaults→zmnoex…umnx(4 USDC vault ATAs: pool/escrow/solidarity/yield) -
join_pool× 3 — Lv1 stakes ($15 each, 50% of credit) deposited to the escrow vault, Metaplex Core position NFTs minted with FreezeDelegate + TransferDelegate plugins:- Member 0 →
4r2Pd9qv…ADc5· join tx2UrRDG…dnLD - Member 1 →
3Sr4M88H…eEnm· join tx3GJUTi…wU8k - Member 2 →
6ymEiWiA…cYiaa· join tx3L7dtn…ceYSJ
- Member 0 →
-
contribute× 3 — cycle 0 fully paid; each $10 installment split across solidarity (1%) / escrow (25%) / pool float (74%); each call also init's a reputationAttestationPDA (SCHEMA_LATE = 2):- Member 0 cycle 0 →
ysSSQJh…6HHW - Member 1 cycle 0 →
3MwScoes…cMYJ - Member 2 cycle 0 →
yTVakGw…iDT
- Member 0 cycle 0 →
-
claim_payoutcycle 0 / slot 0 — Pool PDA signs $30 USDC transfer to member 0,pool.current_cycleadvances 0 → 1,Member.paid_out=true,SCHEMA_CYCLE_COMPLETEattestation minted:- Pool float top-up
4dEaTvFr…pKpe8— deployer adds $7.80 USDC topool_usdc_vault(proxy for the Yield Cascade LP-distribution flow that bridges this gap in production) - Claim tx
5fx4VLEt…qpab— member 0 USDC ATA: 15 → 45 (+$30 received)
- Pool float top-up
-
contributecycle 1 × 3 — same split, member balances rolled forward; new SCHEMA_LATE attestations:- Member 0 cycle 1 →
3hqMZGB…JGBdB - Member 1 cycle 1 →
CFt7rHW…BeY9G - Member 2 cycle 1 →
P3iaunv…sGRmM
- Member 0 cycle 1 →
-
claim_payoutcycle 1 / slot 1 — member 1 receives $30,pool.current_cycleadvances 1 → 2:- Top-up
HwC3ZGd…gWgD· Claim tx4KEmjib…ye1o— member 1 USDC ATA: 5 → 35
- Top-up
-
contributecycle 2 × 3 — final cycle's contributions:- Member 0 cycle 2 →
4T1W7cB…61mJ8 - Member 1 cycle 2 →
5PHr9Qn…sfsQ - Member 2 cycle 2 →
3AQ3jxv…6VvQj
- Member 0 cycle 2 →
-
claim_payoutcycle 2 / slot 2 — member 2 receives $30,pool.status = Completed:- Top-up
4MgZk1C…kZJHH· Claim tx4bjda3t…Kfwc— member 2 USDC ATA: 15 → 45
- Top-up
-
release_escrownegative test (member 0, checkpoint 1) — failed on-chain withEscrowLockedcode 6011 becausemember.on_time_count (0) < args.checkpoint (1). The protocol refused to release the legitimate $22.50 escrow balance because all contributions had been LATE. Durable on-chain enforcement evidence:- Failed tx
4wB8RqiP…f5Mn— log:AnchorError ... release_escrow.rs:91. Error Code: EscrowLocked. Error Number: 6011
- Failed tx
Full ROSCA closed end-to-end on devnet, plus Triple Shield enforcement verified. Protocol init → pool create → vault inits → 3 members joined with USDC stakes + position NFTs → 9 contributions across 3 cycles → 3 payouts (slots 0 → 1 → 2) →
Pool.status = Completed→ 12 reputation attestations on-chain → 2 deterministic guards captured firing (WaterfallUnderflowif pool float can't cover credit;EscrowLockedif member paid late). Seedocs/status.mdanddocs/devnet-deployment.md.
Pool 2 (8XZxRSqU…twbujm, cycle_duration = 3600s) was driven specifically to exercise the M3 instructions that pool 1's late-paying lifecycle skipped: deposit_idle_to_yield + harvest_yield (the full PDF-canonical Yield Cascade) and the positive-path release_escrow (vesting math returns stake to a member who paid on-time).
deposit_idle_to_yield× 2 + pre-fund — 10 USDC moved from pool float to yield_mock vault, plus a 0.5 USDC pre-fund to simulate accrued APY:- Last deposit
3gAbmM48…U3kp· pre-fund26DN91xo…3gf2
- Last deposit
harvest_yield— realized 0.5 USDC, full waterfall (protocol fee 20% → treasury, GF/LP/participants logical earmarks accrued):U1vK5GXM…sdmq· pool float +0.4, treasury +0.1
release_escrowPOSITIVE — member 0 received 5 USDC of vested stake (stake_deposited / cycles_total = $15 / 3):5BvLSatc…HVQm·escrow_balance: 17.50 → 12.50,last_released_checkpoint: 0 → 1,member ATA: 0 → 5 USDC
The protocol's differentiator vs WeTrust / RociFi: distressed members can sell their position to a buyer who picks up the obligations, instead of defaulting and triggering Triple Shield seizure.
- List: member 1 (slot 1) listed at $14 USDC (slight discount vs $15 stake)
4aFv9zbC…tzDu· listing PDA5sQBMvMY…oMB5A - Bug surfaced + fixed in flight: first buy attempt reverted with mpl-core
0x1abecauseTransferV1resets owner-managed plugin authorities (FreezeDelegate / TransferDelegate). Bankrun harness only had defense-in-depthAssetNotRefrozenguards; the positive flow had never run on real mpl-core. Fix shipped: re-approve both plugins back toposition_authoritypost-transfer. Core upgrade2RSZQLtq…36tQ - Buy POSITIVE: a fresh buyer wallet picked up the listing. $14 USDC buyer→seller, atomic re-anchor closed the old Member PDA + minted a new one at the buyer's key (all bookkeeping carried over), NFT thawed/transferred/re-delegated/re-frozen under
position_authority, listing closed. Buy tx3cdG3bWR…cgCpr· new Member PDAAm3iA2sd…oxQF
Pool 3 (D9PS7Q…pDE5, cycle_duration=60s) was provisioned with a fresh wallet set (MEMBER_INDEX_OFFSET=3 → member-3/4/5) so neither Pool 1 nor Pool 2's existing SCHEMA_CYCLE_COMPLETE attestations interfered with the default flow's SCHEMA_DEFAULT (id=3) write. Combined with the devnet-only GRACE_PERIOD_SECS=60 patch (was 7d in production), the grace-elapsed precondition was reachable in a single test run.
contributecycle 0 — slots 0+1 paid LATE (now > pool.next_cycle_at + 60s), slot 2 was SKIPPED byseed-cycle.tspre-flight ATA balance check ($5 < $10 installment) so member-5 became the deliberate defaulter:- Member-3 cycle 0 →
HWeuu9J8…61WEy - Member-4 cycle 0 →
5YhGNfHY…g3auz
- Member-3 cycle 0 →
claim_payoutcycle 0 / slot 0 — deployer floated $15.20 to cover slot-2's missing contribution; member-3 received $30;pool.current_cycleadvances 0 → 1:- Top-up
532qSPCE…xAMsD· Claim tx4DEb5AQo…re7GD
- Top-up
settle_default(1)slot 2 — Triple Shield waterfall fired: drained $0.20 from solidarity vault, stopped at shield 1 because the D/C invariant already held (c_after $30 ≥ d_rem $30),member.defaulted=true, SCHEMA_DEFAULT attestation written, escrow + stake left intact.- Settle tx
34UyAtEP…NeJeG· Member-2 PDA (nowdefaulted=true)GqzmPkW7…SqfHQ
- Settle tx
On-chain msg! summary captured verbatim:
roundfi-core: settle_default cycle=1 member=4sLSCzCJnZFMtaLD6vQsgZ4ywAwYa6joExK9dcM2HvKq
seized_total = 200_000 (= $0.20)
solidarity = 200_000 (= $0.20) ← drained
escrow = 0 ← intact
stake = 0 ← intact
d_rem = c_init = c_after = 30_000_000 (= $30 = pool.credit_amount)
This is the first capture of the shield-1-only quadrant on real funds. The opposite extreme — installment > stake_initial + escrow_so_far — would force shields 2+3 to fire and is covered by bankrun's tests/security_default.spec.ts.
Full M3 protocol surface exercised on-chain across three pools, plus the first browser-signed write loop end-to-end. Across pool 1 (negative paths + claims + close_pool), pool 2 (yield + positive release + Escape Valve), and pool 3 (settle_default + Triple Shield seizure + browser contribute + browser claim_payout), every active M3 instruction now has a real on-chain receipt:
create_pool,init_pool_vaults,join_pool,contribute,claim_payout,release_escrow,deposit_idle_to_yield,harvest_yield,escape_valve_list,escape_valve_buy,close_pool,settle_default, plusroundfi_yield_mock.init_vault. 4 Triple Shield guards captured firing on real funds (WaterfallUnderflow×2,EscrowLocked, shield-1-only seizure). Browser-signedcontribute()+claim_payout()(Phantom → IDL-free encoders → devnet) close the wiring loop — txs37FZUtg7…wg6f(pay) +LKickMQ1…SEv7Ym(receive). An mpl-core owner-managed plugin gotcha (a real production-relevant issue bankrun missed) was surfaced and fixed end-to-end on devnet. Pool 1's close_pool emitted a balanced summary log (total_contributed=$90, total_paid_out=$90) — the lifecycle invariant for a completed ROSCA holds. 16 reputationAttestationPDAs on-chain (13 cycle + 1 SCHEMA_DEFAULT + 1 SCHEMA_LATE from browser contribute + 1 SCHEMA_CYCLE_COMPLETE from browser claim). 10 Solana 3.x Box workarounds + 1 protocol fix shipped this milestone.
The front-end's read path is now wired against the deployed pools (foundation on branch claude/m3-app-wiring-foundation):
- IDL-free pool + member decoders in
sdk/src/onchain-raw.ts(Anchor's IDL gen is broken on Rust 1.95+; we replicate the offsets frompool.rs/member.rsbyte-for-byte). React hooksusePool(seedKey)andusePoolMembers(seedKey)poll every 30s. /homelights up live — the FeaturedGroup card overrides its mock counters with real Pool 2 state (members joined / cycle / installment / credit) when devnet RPC responds, plus a "ROSTER" chip row beneath the avatars showing the three real wallets with slot tags + on-time / contributions tooltips + red border ondefaulted=true. A new<DevnetPoolStatus />row shows all 3 deployed pools side-by-side with status badge + live counters + Solscan links per card./grupos— the catalog now opts cards into an "on-chain · devnet" pill (linked to Solscan) via an optionaldevnetPoolfield on the fixture.g1is tagged → pool 3. When a fixture is also flaggedcontemplated: true(Demo Studio scenarios), the GroupCard's primary CTA flips to a purple-teal "Receber R$ X" button.- Three IDL-free write encoders all under
app/src/lib/:contribute.ts— discriminator522144832000cd5f, 18 accounts (validated end-to-end on devnet)claim-payout.ts— discriminator7ff0843ee3c69285, 14 accounts (validated end-to-end on devnet)escape-valve-buy.ts— discriminatorc48acf6a712d9c54, 15 accounts + 5 mpl-core CPIs at 600k CU (encoder shipped, UI wire deferred)
- PayInstallmentModal + ClaimPayoutModal auto-detect on-chain mode when the connected wallet is a materialized member of the target pool, swap the mock 1500ms timeout for a real
wallet.sendTransaction, render tx hash + Solscan link on success. Both modals surface the protocol economics inline: PROGRESSO DE PAGAMENTO grid (parcelas pagas / restantes / dívida em aberto) + TRIPLE SHIELD GARANTIA grid (stake locked + escrow accumulated + total collateral) so the demo answers the natural "is the user really receiving 100% of credit_amount upfront, regardless of level / installments paid?" question on screen. - Demo Studio +
/gruposmock-mode CTA — the sameClaimPayoutModalis now dual-mode. Chain mode fires the realclaim_payouttx; mock mode (when memberRecord/pool/seedKey props are omitted) drives thesession.claimPayoutMockreducer for Demo Studio scenarios where the contemplated user has no on-chain wallet match. Same UX, same protocol disclosure, different ingress.
Read paths degrade gracefully (status="fallback" → muted "rpc unavailable" line) and the write path falls back to the mock confirm when pre-conditions don't hold, so the localhost demo / unconnected-wallet flow stays unchanged.
Write loop validated end-to-end on devnet (2026-05-07). TWO browser-signed txs, opposite sides of the ROSCA cycle:
- Pay — Member-3 imported into Phantom, connected on
/home, FeaturedGroup flipped to ON-CHAIN · DEVNET reading Pool 3 live,PayInstallmentModalshowed the green ON-CHAIN banner, user signed in Phantom, the IDL-free encoder dispatchedcontribute(cycle=1, schemaId=SCHEMA_LATE)and the program landed it cleanly. Tx37FZUtg7…wg6f— first browser-signedcontribute()in RoundFi history. Member-3's USDC ATA dropped 45 → 35.- Receive — Member-4 imported via the new
pnpm devnet:export-pkhelper, connected on/home. FeaturedGroup detectedmember.slot_index == pool.current_cycle == 1and surfaced the new purple-teal "Receber R$ 165" CTA next to "Pagar parcela". Click →ClaimPayoutModalshowed the ON-CHAIN banner withclaim_payout(cycle=1)+ four-bullet state transition preview. First attempt reverted withWaterfallUnderflow(pool float $7.60 < credit_amount $30) — the protocol's solvency guard working as designed, captured live. The newpnpm devnet:seed-topupcompanion script computed the gap (credit − spendable + cushion) and bridged it from the deployer (tx3iFuuEwP…s9VQ). Retry landed claim_payout txLKickMQ1…SEv7Ym. Member-4's USDC ATA: 35 → 65,pool.current_cycle1 → 2,member.paid_out=true,SCHEMA_CYCLE_COMPLETEattestation written.Both write paths use the same byte-for-byte IDL-free encoder methodology (precomputed Anchor discriminator + manual account list mirroring the program's
<Accounts>declaration). The remainingescape_valve_buyencoder (also shipped in this PR) inherits the same confidence even before its own end-to-end run.
The Mainnet IDs below validate the CD pipeline against real-cluster conditions and give reviewers a clickable Mainnet Solscan link as evidence of execution. The protocol is not initialized; production launch is gated behind the Phase 3 milestone in docs/status.md. Procedure: docs/devnet-deployment.md §8.
| Program | Program ID | Solscan |
|---|---|---|
roundfi-core |
_FILL_ME_ |
view |
roundfi-reputation |
_FILL_ME_ |
view |
roundfi-yield-mock |
_FILL_ME_ |
view |
roundfi-yield-kamino |
_FILL_ME_ |
view |
Deploy tx (any of the four uploads): _FILL_ME_ (view)
| Layer | Tech |
|---|---|
| Smart contracts | Rust + Anchor 0.30 |
| Tests | anchor test + solana-bankrun |
| NFTs | Metaplex Core |
| NFT metadata | Client-supplied URI today (https:// / ipfs:// / ar:// accepted); Arweave-via-Irys upload pipeline planned post-mainnet — IRYS_NODE_URL already wired in config/clusters.ts |
| Attestations | In-house SAS-compatible module (Devnet) → official SAS (Mainnet) |
| Yield | Mock adapter (Devnet) → Kamino CPI (Mainnet). roundfi-yield-kamino::deposit() does a real deposit_reserve_liquidity CPI on Kamino Lend mainnet program; harvest() ships in next milestone (park-only mode until then). |
| Stablecoin | USDC |
| Backend | Node.js + TypeScript + Fastify + Prisma + PostgreSQL — indexer scaffold landed in M3 (services/indexer/: webhook handler + IDL-free Anchor log decoder + getProgramAccounts backfill against the same SDK helpers the front-end uses); see services/indexer/README.md for run instructions and docs/architecture.md for design |
| Frontend | Next.js 14 + React 18 + framer-motion 11 + Tailwind 3 (landing) + @solana/wallet-adapter + @coral-xyz/anchor |
| Cluster | Devnet → Mainnet (env-driven) |
git clone https://github.com/alrimarleskovar/RoundFinancial.git
cd RoundFinancial
pnpm install
pnpm --filter @roundfi/app dev
# -> http://localhost:3000/To use the live wallet flow on devnet, install Phantom and switch its network to Devnet before clicking "Connect Wallet".
See docs/devnet-setup.md for the full walkthrough. Short version (WSL2 / Linux / macOS):
cp .env.example .env
solana config set --url https://api.devnet.solana.com
mkdir -p keypairs && solana-keygen new -o keypairs/deployer.json
export ANCHOR_WALLET=$(pwd)/keypairs/deployer.json
pnpm run devnet:airdrop # 2 SOL (repeat as needed)
pnpm run devnet:deploy # build → keys sync → build → deploy
# copy the printed IDs into .envAll 20 roundfi-core instructions are deployed and exercised on devnet (see On-chain Deployments). The ping dev-only smoke instruction stays in the program as a quick connectivity check.
The repo ships an app/vercel.json so the deploy works with one tweak in the dashboard:
- Sign in at vercel.com → Add New → Project → import
alrimarleskovar/RoundFinancial. - Set Root Directory to
app(this is the only manual step — Vercel needs to findnextinapp/package.json, not the workspace root). - Leave everything else at the default. Vercel reads
app/vercel.jsonand:- Runs
cd .. && pnpm install --frozen-lockfileso the pnpm workspace resolves (@roundfi/sdk,@roundfi/orchestrator). - Builds the app:
pnpm buildinsideapp/. - Auto-detects Next.js inside
app/and applies all framework optimizations.
- Runs
- Click Deploy. ~2 minutes.
No env vars required for the public landing — wallet adapter handles its own RPC defaults (devnet). For browser-signed write paths against devnet (now live), the deploy uses:
NEXT_PUBLIC_SOLANA_RPC_URL(Helius / public devnet)NEXT_PUBLIC_ROUNDFI_CORE_PROGRAM_IDNEXT_PUBLIC_ROUNDFI_REPUTATION_PROGRAM_ID
The ignoreCommand in app/vercel.json skips rebuilds when only docs/grant/programs/tests change — saves build minutes on doc-only PRs.
Apache-2.0 — full text in LICENSE. Covers the four Anchor programs (programs/roundfi-core, roundfi-reputation, roundfi-yield-mock, roundfi-yield-kamino), the IDL-free SDK (sdk/), and the Next.js app (app/). Reputation scoring methodology is documented openly in docs/en/04-behavioral-reputation-score.pdf so any third party can audit how the score is generated. A future hosted B2B scoring service (Phase 3) may ship under a separate license; not yet released.
- Repo: https://github.com/alrimarleskovar/RoundFinancial
- Hackathon: Colosseum 2026