Skip to content

Jsv analytics dashboard - #271

Merged
Sendi0011 merged 20 commits into
mainfrom
jsv-analytics-dashboard
Oct 16, 2026
Merged

Sendi0011 merged 20 commits into
mainfrom
jsv-analytics-dashboard

Conversation

@Sendi0011

@Sendi0011 Sendi0011 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Description

This branch delivers two related pieces of work on top of main:

  1. Protocol analytics dashboard (f9ed64b, 89c0b1c, cb52797) — a protocol-wide analytics dashboard backed by a new /api/v1/protocol/summary route and a subgraph/ package.
  2. Vault-backed yield allocation (e514451 … a85c8db) — an opt-in feature that lets flexible pools move idle capital into an external yield vault, gated by governance and a liquidity buffer.

Vault-backed yield allocation

Flexible (flexible) pools can now allocate idle capital to an external, yield-bearing Soroban vault. The feature is deliberately constrained:

  • Vault-agnostic adapter — works with any contract implementing the VaultAdapter interface (deposit, withdraw, share_price, max_redeemable). A MockVault ships behind the mock cargo feature for tests and testnet demos.
  • Governed — the vault address is proposed and passed through the existing governance voting flow. Allocation actions ride the Custom proposal path and are dispatched to the pool via CPI, so there is no ProposalType enum change.
  • Liquidity buffer — a configurable share of the pot (default 20%) is kept liquid so withdrawals always work. On withdrawal the pool auto-pulls from the vault and reverts with a clear "vault illiquid" error if the vault cannot redeem.
  • De-allocation + emergency lock — apply_yield_deallocation degrades to a partial withdrawal; YieldLocked stops new allocations while still allowing de-allocation.
  • Pro-rata accounting — realised yield is credited to members by principal using integer-only, floor-rounded maths (rounding favours the pot); cost basis advances so yield is never double-counted.
  • Safety — auth on every state-changing entrypoint, checks-effects-interactions before any CPI, checked arithmetic (release profile has overflow-checks = true), and events for every fund movement.

Smart contracts

  • New yield-vault crate: VaultAdapter/VaultClient, VaultError, events, types (SHARE_SCALE, DEFAULT_BUFFER_BPS, BPS_DENOMINATOR), and the MockVault.
  • flexible: allocation/de-allocation entrypoints, buffer configuration, yield accounting (sync_yield), views (yield_vault, yield_shares, yield_cost_basis, yield_buffer_bps, yield_locked, max_allocatable_amount, yield_position, unrealised_yield), and buffer-safe withdrawals.
  • governance: dispatch_custom routes alloc/dealloc actions through the pool CPI.

Frontend

  • Bindings + a useYieldAllocation data hook for yield state and actions (apply, deallocate, sync, set buffer, set lock).
  • Governance: create yield allocation proposals and render the decoded action/amount/vault in the voting UI.
  • Yield dashboard: vault position, unrealised yield, share price, buffer, and max allocatable, with allocate/deallocate/sync/buffer/lock controls.
  • Withdraw flow: illiquidity banner and guidance.
  • en/es copy for all new strings.

Docs & deployment

  • docs/plans/2026-10-16-yield-allocation.md (design spec) and docs/security/yield-allocation-threat-model.md (threat model).
  • README + smartcontract/README.md updates.
  • smartcontract/scripts/deploy.sh now builds (mock feature), uploads, deploys, and initializes the mock vault on testnet, and records its wasm hash / contract id in deployments/stellar-testnet.json.

Type of Change

  • feat: new feature
  • fix: bug fix
  • chore: maintenance, tooling, dependencies
  • docs: documentation only
  • refactor: code restructuring (no functional changes)
  • test: adding or updating tests

How Has This Been Tested?

  • cargo test passes (smart contracts) — flexible 79, governance 42, yield-vault 4
  • cargo clippy --workspace --all-targets -- -D warnings passes
  • cargo fmt --all --check passes
  • pnpm lint passes (frontend)
  • pnpm build succeeds (CI "Frontend – Lint & Format Check" + Vercel preview)
  • pnpm test:unit — 443 node unit tests pass
  • React component tests — new vote-card-yield and yield-dashboard-vault suites pass (7 tests)

Notes:

  • Yield accounting has dedicated edge-case tests (illiquidity, rounding, unauthorised caller, zero amounts).
  • Remaining full-suite component-test failures (flexible-form, group-page, transactions, archived-pool, deposit-calendar) were confirmed pre-existing/flaky by reproducing them on the base commit — they are unrelated to this change.

Checklist

  • My code follows the coding conventions of this project
  • I have added/updated tests if needed
  • I have updated documentation if needed
  • My changes generate no new warnings or errors

Screenshots (if applicable)

mijinummi and others added 19 commits August 20, 2026 13:48
…nt + test placement

Adopts mijinummi's protocol analytics dashboard (API route + Dashboard component)
and the subgraph scaffolding (The Graph protocol indexer). Fixes two CI failures:

1. frontend/__tests__/pool.test.ts imported matchstick-as (a subgraph test
   framework not in frontend's deps) — moved to subgraph/tests/pool.test.ts
   where Graph projects expect matchstick tests to live. This also removes
   it from vitest's test roots (__tests__/).
2. prefer-const (5) and no-explicit-any (1) lint errors in pool.test.ts and
   route.ts fixed; route.ts error: any replaced with instanceof Error check.
3. Prettier run on route.ts and Dashboard.tsx.
Specifies a vault-agnostic adapter interface, a test mock vault, pool-side
shared accounting with a liquidity buffer, and a governance flow that reuses
the existing Custom proposal type so no enum or stored-proposal schema changes.
Documents custody, share-value, and illiquidity risks.
Introduces the jointsave-yield-vault crate with the VaultAdapter trait
(deposit, withdraw, share_price, max_redeemable, total_shares,
total_assets), a shared VaultError enum, yield-allocation events, and the
SHARE_SCALE / liquidity-buffer constants. The pool will depend only on this
interface, so any vault implementation can be plugged in.
Implements MockVault as a self-contained VaultAdapter: 1:1 first deposit,
live share price from its token balance, floor-rounded withdrawals, and a
set_locked_assets admin control to simulate illiquidity deterministically.
Includes unit tests and a CI wasm build step.
Extends the Custom proposal dispatcher: a Custom proposal carrying an
'action' parameter (alloc/dealloc) is forwarded via CPI to the pool's
apply_yield_allocation / apply_yield_deallocation entrypoints, using the
existing i128 param encoding and a strkey vault parameter. Proposals without
an 'action' parameter keep the previous behaviour, so the closed ProposalType
enum and stored proposal schema are unchanged. Adds mock-pool tests.
Adds apply_yield_allocation (admin or governance only) which moves idle
capital into a vault implementing the adapter, tracks the pool's shares and
cost basis, and enforces a configurable liquidity buffer (default 20%) so the
pot always keeps enough liquid for withdrawals. Adds set_yield_buffer and
read-only views. The yield-vault mock is feature-gated so it is not linked
into the pool's wasm.
Adds apply_yield_deallocation (admin, governance, or any member) which
redeems shares and degrades gracefully to a partial recovery when the vault
is illiquid, removing proportional cost basis. Withdrawals now pull the
shortfall back from the vault automatically and only revert with a clear
'vault illiquid' error when the pot is genuinely short, so member funds are
never trapped. Adds set_yield_locked emergency mode.
Adds sync_yield (admin, governance, or any member) which values the pool's
vault position at the live share price, credits any gain to members pro-rata
by principal balance using floor division, and advances the cost basis by
exactly what was credited so the rounding remainder stays in the pot as
still-unrealised yield. Adds yield_position and unrealised_yield views.
Covers illiquidity (partial de-allocation, locked vaults, withdraw panic path),
buffer enforcement (zero buffer), rounding and zero-amount rejections, paused
pool behavior, and the governance Custom dispatch paths (double-vote/unauthorized
already covered). All existing and new tests pass.
Extends useJointSaveContracts with fetchYieldAllocationState and hooks to
apply allocation, deallocate, sync yield, set buffer, and set lock on the
flexible pool. Mirrors existing contract interaction patterns with loading
state and proper argument encoding.
Adds framework-free helpers (buffer/max-allocatable/share-price/unrealised
gain) mirroring the contract invariants with unit tests, plus useYieldAllocation
which loads the on-chain position and exposes apply/deallocate/sync/buffer/lock
actions that refetch after each mutation.
Extends the create-proposal dialog with an Allocate/De-allocate option for
flexible pools that encodes a Custom governance proposal carrying action,
vault and amount parameters (16-byte BE i128), matching the contract's
dispatch_custom routing. Adds pure param-encoding helpers with unit tests
and en/es copy.
Parses proposal parameters out of the on-chain map and renders the decoded
action, amount and vault on each yield proposal card so members know what
they are voting on. Unifies the duplicate GovernanceProposal types onto
lib/governance as a single source of truth and adds decode/format helpers
with unit tests.
Adds a vault-allocation section to the flexible-pool yield dashboard showing
the position value, unrealised yield, share price, liquidity buffer and
available-to-allocate, plus controls to allocate, de-allocate, sync yield and
toggle the vault lock. Reuses the useYieldAllocation hook with loading/error/
empty states and adds en/es copy.
Adds an in-UI banner for flexible pools when the yield vault is locked with
allocated shares, warns about withdrawal limits, and updates the withdraw
hint to reflect automatic on-chain de-allocation from vaults. Fetches yield
state to detect illiquidity.
Add manual-mock exports for the yield allocation hooks so the
group-actions component test can render the extended withdraw flow,
and cover the vault allocation dashboard section plus the yield
proposal details in the voting UI.
Add a threat model for the vault-backed yield feature, document the
mock vault and its deployment in the smart-contract README, extend
deploy.sh to build/upload/deploy/initialize the mock vault and record
its wasm hash and contract id, and reference the feature from the
root README.
@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
joint-save Ready Ready Preview Oct 16, 2026 6:21pm UTC
joint-save-y4yx Ready Ready Preview Oct 16, 2026 6:21pm UTC

The CI clippy job runs with --all-targets, which lints test code too and
rejected two bindings that are only used for their side effects in the
yield allocation edge-case tests.
@Sendi0011
Sendi0011 merged commit 3bc555f into main Oct 16, 2026
17 checks passed

This branch was successfully deployed

2 active deployments
Preview – joint-save-y4yx — a85c8dbc Deployed Oct 16, 2026 by vercel[bot]
Preview – joint-save — a85c8dbc Deployed Oct 16, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants