feat(scenarios): add GoonFi state preparation - #13
92Infinitus92 wants to merge 12 commits into
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
e224b2b to
aad98d6
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 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.
60160c9 to
0bc5e39
Compare
The Tessera, HumidiFi and GoonFi parameter structs deserialized their fields as snake_case, so a client sending surfnetPort the way the pump, get_template and search_constant_options tools expect it was ignored and the read fell back to port 8899. Scenario tools now share one convention.
|
@greptileai The address is checked before the bytes are used: |
|
You're right on the core point. Given the documented library contract, the MCP path reads each account by address and passes the paired values, matching the existing pump graduation builder pattern. The remaining risk is caller misuse rather than an actionable defect in these builders. I would withdraw the P2 merge blocker; an API redesign could be considered separately if provenance must be enforced for all direct 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.The PR appears safe to merge.
Summary
The PR adds GoonFi market discovery and scenario preparation using the shared raw-layout engine.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR RPC[Surfnet RPC] --> Discovery[GoonFi market discovery] Discovery --> Market[Validated market] Market --> Price[Price scenario builder] Market --> Liquidity[Liquidity scenario builder] Price --> Oracle[Oracle price and freshness overrides] Price --> Band[Market reference-band override] Liquidity --> Base[Base-vault balance override] Liquidity --> Quote[Quote-vault balance override] Liquidity --> Fresh[Oracle freshness override]Reviews (14) · Last reviewed commit: "docs(goonfi): say that the freshness ove..."