feat(scenarios): add GoonFi state preparation - #13
Conversation
|
Two improvements in the PR:
Tests could not run: Rustup attempted to write into a read-only toolchain directory. |
The catalog isolation issue from the earlier review is fixed in the latest commit. Review was static; tests were not run. |
Tests could not run: rustup attempted to write to a read-only directory. |
9af2fc5 to
61a9091
Compare
GoonFi is a two-account dark AMM with no IDL: a 32-byte external price oracle plus a 2048-byte market carrying the reference band that guards it. - Four raw-layout templates over the two accounts (price, reference band, freshness, stale quote), plus a live market catalog read from program accounts. - Two builders. Price moves the oracle bid and ask together with the market's reference band and a persistent freshness stamp, because the deployed program rejects a decoupled move with 0x24. Liquidity resolves both token vaults from the market's own pointers and scales their balances. - Three MCP tools on the generic scenario path: list_goonfi_markets, create_goonfi_price_scenario and create_goonfi_liquidity_scenario. No protocol HTTP endpoints. - The Slot raw encoding now takes a width, so the 4-byte freshness field no longer clobbers the decay multiplier stored beside it. - Live gated tests against the deployed program. The shared live-test helper duplicates the Tessera branch's on purpose; they fold together when the branches converge.
- Catalog discovery skips a market that fails validation with a warning instead of aborting the whole scan, so one obsolete market can no longer hide every valid one. An empty catalog from a program that does own markets stays an error. - Vault balances are read through TokenAccount::unpack and checked against the market's own mint: an owner-and-length check also admits an 82-byte mint, whose bytes at the amount offset would be misread as a balance. - GoonfiMarket is non_exhaustive, so a market and its oracle can only be paired through validate, which reads the oracle from the market's own pointer.
`non_exhaustive` only blocked building a GoonfiMarket from scratch outside the crate; the fields stayed public, so a caller could still re-point a validated pair's oracle. Making both private leaves `validate` as the only way to pair a market with an oracle, and it reads that oracle from the market's own pointer.
The fields are private, so a caller that legitimately needs to know which market and oracle a validated pair refers to had no way to ask.
A market account does not record its own address, so `validate` had to take the caller's word that the address and the data describe the same market. Its vaults do record it: a GoonFi vault is a token account whose authority is the market. `validate` now takes the base vault the market itself names and compares that authority, the same shape of cross-check the pump graduation builder makes through its curve vault's mint. The liquidity builder applies it too, from accounts it already holds. Neither path costs an extra round trip: discovery carries the base vault alongside the mints and oracle so it batches with them, and the MCP market fetch reads it in the same call as the oracle. Verified against all 33 live markets - every one names its market as the base vault's authority.
The BisonFi branch was squashed and renamed `load_protocol_overrides_without_idl` to `load_raw_layout_overrides`; GoonFi registers its two raw account shapes through it, the same call BisonFi makes for its own.
e224b2b to
aad98d6
Compare
The balance is read from the account passed in but written to the vault address decoded from the market, so a vault of the right mint belonging to another market would scale the wrong balance into this one - a requested drain could top the vault up instead. The authority check now lives inside the balance read, where it covers the quote side too, and the base-only call it replaces is gone.
Validate vault and oracle addresses against the market's pointers before reading balances or constructing overrides. Preserve the existing RPC reads and generic scenario templates. Add mismatch regressions and update MCP, discovery, and live-test callers.
Stacked on #8 — GoonFi is the same mechanism class as BisonFi and Tessera (PMM, no IDL) and reuses the raw-layout engine BisonFi introduced.
0x24. Liquidity resolves both token vaults from the market's own pointers and scales their balances through the genericspl-token-account-balancetemplate.list_goonfi_markets,create_goonfi_price_scenarioandcreate_goonfi_liquidity_scenario. No protocol HTTP endpoints and no custom RPC methods.Slotraw encoding now takes a width, so GoonFi's 4-byte freshness field no longer clobbers the decay multiplier stored beside it. Existing 8-byte slot fields are unchanged.0x1, a dislocated quote with a coupled band fills at the prepared price, an aged oracle rejects with0x15, and a price moved out of its band rejects with0x24.Greptile Summary
The PR adds GoonFi market discovery and price/liquidity scenario preparation using raw account layouts, together with MCP tools and protocol tests.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR U[MCP request] --> M[Fetch selected market] M --> P[Resolve oracle and vault pointers] P --> V[Validate owners, layouts, addresses, mints, and authorities] V -->|Price| PS[Build price, reference-band, and freshness overrides] V -->|Liquidity| LS[Scale selected vault balances and add freshness override] PS --> S[Register scenario] LS --> SReviews (7): Last reviewed commit: "fix(goonfi): bind account inputs to mark..." | Re-trigger Greptile