feat: index-vault core — iPOT liquid index token, NAV engine, redeem queue, keeper cranks - #79
Open
YD811 wants to merge 4 commits into
Open
feat: index-vault core — iPOT liquid index token, NAV engine, redeem queue, keeper cranks#79YD811 wants to merge 4 commits into
YD811 wants to merge 4 commits into
Conversation
…t, NAV snapshot, redeem queue, deploy seam - New accounts: StrategyConfig (["strategy", pot]), TokenAllowlist (["allowlist"], 100 mints, 3 classes), StrategyPosition (["position", pot, mint, route]), RedeemRequest (["redeem", pot, member, id]). - PotAccount tail carve: index_mint + is_flagship + Option<NavSnapshot> (reserved 128→70, layout-compatible — old accounts decode as default/None). - 15 new instructions: allowlist init/set, index bootstrap (init_index_mint + init_strategy_config + init_position + init_position_vault — one init per ix, the 4KB BPF stack frame does not fit two), deposit_base, redeem_instant, request_redeem/settle_redeem/ cancel_redeem, deploy_to_strategy/withdraw_from_strategy, update_nav_snapshot, set_strategy_paused, update_strategy_config. - Guards: deposit min/max, TVL cap, NAV staleness (slots) + deviation cap, idle-buffer floor on deploys, keeper allowlist, weights sum=100%, global mint allowlist. Redemptions are never pause-gated. - Custody: funds only in vault-PDA-owned token accounts; keeper cranks can never pay anyone but the requester's own ATA. - Legacy strategy_vault StrategyConfig renamed LegacyStrategyConfig (plain struct, no layout/discriminator impact). - IDL: scripts/patch_idl_index.py (deterministic, idempotent, self-checking) — 53 ix, 14 accounts, 100 errors; copies refreshed in sdk/web/keeper. - Tests: tests/index_vault.test.ts — 12 cases (bootstrap, NAV repricing, caps, instant + queued redeem, buffer floor, keeper auth, pause semantics). Full suite 30 passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- pda.ts: getStrategyConfigAddress / getAllowlistAddress / getIndexMintAddress / getStrategyPositionAddress / getPositionVaultAddress / getRedeemRequestAddress. - index-vault.ts: builders for the full surface (bootstrap, deposit, instant+queued redeem, settle/cancel, deploy/withdraw, NAV crank, pause, config update), ATA helpers (idempotent create — vault ATAs are client-created by design), fetchStrategyConfig/fetchPositions/fetchPendingRedeems, getNavPerShare, computeBookNav. tsc clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…settler - index-crank.ts: discovers StrategyConfigs served by this keeper key, writes book-value NAV (idle buffer + Σ position cost bases; exact while routes hold base at book — market pricing per route plugs in with the protocol adapters), settles pending RedeemRequests the buffer can serve (rate-limited per tick). - Idempotent (non-overlapping ticks), retries with exponential backoff, per-tick settle cap, structured logs, metrics export. - Keeper key via KEEPER_KEYPAIR_PATH / KEEPER_KEYPAIR_JSON (secret manager) — crank-only identity, cannot route funds anywhere but a requester's own ATA. - Wired into index.ts behind KEEPER_ENABLE_INDEX_CRANK (default on, no-op without a key). .env.example documents the new knobs. tsc clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, flagship pin - lib/token-registry.ts: curated client registry (verified liquid mints only — USDC/USDT + SOL/JitoSOL/mSOL/bSOL/jupSOL), 3 classes, per-token defiRoutes, composition validator mirroring on-chain guards. Must stay ⊆ on-chain allowlist. - hooks/useIndexVault.ts: NAV/price/idle reads (30s), previewShares/previewPayout, useDepositBase (1% min-shares floor), useRedeemIndex (instant → queue fallback). - components/IndexVaultPanel.tsx: price/share + NAV + instant liquidity, deposit with mint preview, redeem with instant/queued state; renders only when the pot has a StrategyConfig — classic SOL flow untouched, mock mode unaffected. - Flagship pin: lib/flagship.ts (env NEXT_PUBLIC_FLAGSHIP_POT → on-chain flag → mock name fallback) wired into / grid and /leaderboard (pins above any sort). - tsc clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The flagship DeFi index-vault layer: deposit USDC → mint a liquid index token (iPOT) at NAV → capital deploys into configured index legs under on-chain caps → instant redemptions from an idle buffer, bigger ones through an escrowed queue.
On-chain (all additive, layout-compatible):
StrategyConfig(["strategy", pot]) — weights (≤10 legs, Σ=100%), idle buffer, TVL/deposit caps, NAV guards, keeper identityTokenAllowlist(["allowlist"]) — global mint allowlist, 100 slots, 3 classesStrategyPosition+ position escrow — per-leg cost basis; the exact seam Kamino/Meteora CPI adapters plug into (Phase 2)RedeemRequest— escrowed redemption queue, priced at settlement NAV, permissionless settle, cancellableindex_mint,is_flagship,Option<NavSnapshot>— old accounts decode unchangedCustody invariant: funds only in vault-PDA-owned token accounts; the keeper cannot pay any wallet except a redeeming member's own ATA.
Off-chain mirror: SDK (PDAs + builders for the full surface, tsc clean) · keeper NAV crank (60s, book-value) + redeem settler · web (token registry, iPOT deposit/redeem panel with instant/queued fallback, flagship pin) · deterministic IDL patcher (
scripts/patch_idl_index.py) since anchor 0.30.1 IDL-gen is broken on modern rustc.Notes for review
initper instruction: two inits in one Accounts struct blow the 4KB BPF stack frame on current platform-tools — hence the split bootstrap (init_index_mint → init_strategy_config; init_position → init_position_vault) and client-created vault ATAs.StrategyConfig(strategy_vault.rs) renamedLegacyStrategyConfig— not an account, no discriminator/layout impact.update_strategy_configloosening changes are NOT timelocked yet — flagged in docs as a pre-mainnet TODO to wire into PendingRiskParams.Tests
Full suite 30 passing (18 existing + 12 new) against localnet (
solana-test-validator --bpf-program GJap9… pot_vault.so): bootstrap, NAV repricing, deposit caps, instant + queued redeem, idle-buffer floor, keeper auth, deviation guard, pause semantics (deposits blocked, exits open).Deploy
Devnet redeploy pending (upgrade authority = deployer 9HCK3…, program account already extended; blocked on ~0.6 faucet SOL). Mainnet: gated on devnet e2e + YD sign-off — runbook in the follow-up docs PR.
🤖 Generated with Claude Code