Skip to content

Product Timeline

Development phases and status. Updated June 2026 (v3.0 model reconciled).

Platform Core

✓ Done

  • Core smart contracts (4 contracts — v3-11 absorbed PlatformEscrow; down from 6)
  • SIWE authentication + JWT
  • SumSub KYC integration + SBT minting
  • Pool creation & management (admin)
  • Investment (atomic deposit + LP mint, no separate escrow — v3-03 / v3-11)
  • Investor portfolio view
  • Redemption request flow (single-stage admin approve + PENDING_RESERVE — v3-04; pool_type removed v3-01)
  • Fund management (funds, fund_members)
  • Notification system (V1 — email + in-app; rebuilt on notification_events/notifications/notification_deliveries in v3-103, live SES bounce/complaint ingestion)
  • RBAC (Admin / Operator / Fund Manager)
  • NAV oracle integrated into PlatformPool 🟠 PD1 (Decided)

▶ In Progress

  • NAV update flow (admin panel)
  • 24h timelock enforcement
  • Portfolio NAV display (investor UI)
  • Writedown UX (tone + transparency)
  • Admin panel V2 cleanup
  • Yield distribution flow (claim-based, MANUAL_CLAIM only)
  • Pool lifecycle auto-transitions (scheduler)

▶ Post-maturity repayment — built, waiting on a manual deploy and two migrations

Written in code, not live: migrations 0189 / 0190 are not applied to dev and the API is a manual deploy:dev:api. The FE/BE legs need no contract change; the one contract item below is built and already on chain, waiting only for a pool to be created from the new factory.

  • Wizard creates FIXED_MATURITY + epoch; plan columns redemption_term_epochs · epoch_date_basis · epoch_roll_day (0189) 🔨 v3-132
  • Deploy writes every cycle's funding date under a clock; redemption_epochs.funding_date records what landed (0190); indexer fix 🔨 v3-133
  • Funding-date reminder gated on unwritten cycles rather than epoch_cycle_mode — ⚠️ one code seam still blocks it firing 🔨 v3-135
  • Per-cycle confirm (epoch_id) + a funding-date ordering guard in the endpoint (not in the contract) 🔨 v3-139
  • Role grants follow the signer; bootstrap PAUSER handed over before it is taken away 🔴 v3-138
  • ✅ Yield accrual ends at settlement, not at request (contract) — the last MVP item, and the one place the engine paid the wrong people on this product. Shipped 2026-08-20 and on chain 2026-08-21; new pools only, and no pool created from the new factory yet 🔧 v3-131

○ Planned

  • Maturity anchored per investor (contract; out of MVP scope) 🔧 v3-131
  • over_funding_detected copy fix — the mail tells fund managers a leftover carries to the next cycle; it does not 🔴 v3-137
  • DocuSign term sheet integration 🟠 PD2
  • Oracle fallback (PD4 — Decided: no fallback) 🟠 PD4
  • KAIA mainnet dual-deploy
  • Multi-sig admin controls (v3-37 shape decided: Admin 3-of-5, Pauser a separate 2-of-3)

Two entries left this list rather than shipping. "Email notification system" was a duplicate of the Done row above. "Reserve fund mechanics" (BD4) is resolved, not pendingR8 settled that the reserve is redemption liquidity and never absorbs loss, so there are no further mechanics to build: updateNAV's reserveConsumed is always 0 and the contract rejects anything else. First-loss is the Junior tranche or the manager's equity buffer.

❓ Open / TBD

  • Secondary market / LP transfers 🟡 BD5
  • Analytics dashboard
  • Mobile app

Note: Multi-stablecoin (USDC/USDT/DAI, USD-backed) is supported per-pool (one recommended) — see 04-pool-models. KYC/KYB gating is live (per-pool, v3-10).


Joob Pool Integration (R21)

Joob (Grab JV) eNote Finance fund integration. Hybrid model: Joob API (fund financials) + On-chain (RPS token for investor positions).

Ref: Notion — Joob Pool Integration To Do | API Spec Doc

ℹ️ Part of this section is based on the March spec — the current SoT is Grab Joob API — Aset Integration (+ second-round request). Resolved after review (2026-06-16): ① total_rni = gross confirmed — code yield-distributions.post.create.ts takes gross input → computes net via net_yield_fee_config (admin/perf fee) (if NULL, net=gross). Integration doc #7 is stale. One remaining line to confirm: whether rni is already net of Joob-side LOF/WHT (independent of the Aset fee layer). ② DPD = per-bucket (30/60/90) implementation is final for Joob (corrected below; ⚠️ superseded for the master route on 2026-08-19 — it serves 30/60 only and retired bucket 90 in favour of /risk/nonperforming, see Guest API surfaces) — only the denominator (active_loan_count/outstanding) is a second-round request. (The Aset-side ingest/data model is being generalized to dynamic, jurisdiction-defined buckets for non-Joob regimes — v3-59.)

✓ Done (Phase 1 — Spec)

  • Joob API spec written + call completed (3 endpoints: Fund Summary, Fund History, DPD Risk)
  • RPS token contract confirmed: 0x3f9c...1403 (Kaia)
  • DB schema: operating_currency, fx_rate columns added to pools (schema.sql L322-323)
  • Admin API types: operatingCurrency, fxRate mapping defined (admin-web/shared/api/pools.ts)
  • total_rni = gross confirmed (mgmt/perf fee not applied, net interest = interest - LOF - WHT)
  • Investor data: not provided by Joob → replaced with on-chain balanceOf + Transfer event indexing
  • DPD: per-bucket (30/60/90) implementation (Joob /risk/dpd/{bucket} per-bucket calls) — changed from the March "buckets not needed" plan. ⚠️ Fund route only as of 2026-08-19; the master route dropped bucket 90 (dpd-exclude-90) and keys its aggregate by month — Guest API surfaces. active_loan_count/outstanding denominator not included → second-round request

⚠️ The phase dates below are from the March plan and have lapsed

Phases 2–4 were scheduled for April/May 2026. Do not read the headings as current status. Where a line could be checked against the code in the 2026-08-06 pass it is marked ✅ or ⛔ below; the rest are not re-verified here, and the live status lives in the Notion SoT linked above rather than on this page.

▶ Phase 2 — DB & Backend (was ~4/1)

  • pools.post.create.ts: accepts operating_currency, fx_rate
  • pools.patch.update.ts: both fields wired
  • Manual Joob Pool creation + lp_token_address = RPS contract — not re-verified
  • ShardLab/Hashed deposit + manual portfolio_positions creation — not re-verified
  • Investability-state logic: non-investors CLOSED, investors ACTIVE (lifecycle_status + visibility) — not re-verified
  • Finalize pool values per the contract (lockup, penalty, min investment) — commercial, not code

○ Phase 3 — UI (was ~4/15)

  • Admin pool-form.tsx: operating_currency, fx_rate input fields
  • Pool Detail pool.$id.tsx: Fund Statistics card (FX banner dropped — v3-24, USD-only, no investor FX disclosure)
  • Portfolio portfolio.tsx: return % display + CLOSED pool button hide
  • Pool card: operating currency tag (dropped — operating_currency backend-only, v3-24)
  • Admin: Joob Pool dedicated management (fee tracking, DPD risk monitor)
  • Net Yield calculation logic: Admin fee 1%/yr (quarterly) + Perf fee 20% (>15% hurdle, at maturity)

○ Phase 4 — API Integration (was early May)

  • ✅ Scheduled fund-data sync exists (fund-data.scheduler.sync) → external_pool_data_snapshots
  • ✅ TVL snapshot cron exists (pools.scheduler.tvl-snapshot) → pool_tvl_history
  • ✅ On-chain LP Transfer indexing exists (onchain-indexer.scheduler) → portfolio_positions
  • Investor Position: on-chain balanceOf + Fund Summary hybrid — not re-verified

❓ Next Cycle

  • Pool smart contract design/deployment
  • API sync → on-chain transition
  • IRR calculation (cashflow-based, Aset self-computed)
  • Recovery Rate (NPL 0% — not needed yet)
  • Per-loan detail data after eNote v2 update (April+)