# Raydium Stable Swap event coverage report — 0.7.52 final ## Scope `0.7.52` closes the `raydium_stable_swap` tranche after `0.7.51 raydium_amm_v4`. Canonical local decoder code: ```text raydium_stable_swap ``` Canonical program id validated by local corpus: ```text 5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h ``` Stable Swap is handled as a Raydium legacy AMM-style program with a one-byte instruction discriminator layout. Anchor-like 8-byte discriminants remain upstream discovery evidence only and are not business proof. ## Final implementation status Implemented and locally validated: - `kb_lib/src/dex/raydium_stable_swap.rs`. - `RaydiumStableSwapDecoder` re-exported through `kb_lib/src/dex.rs` and `kb_lib/src/lib.rs`. - Stable Swap route in `DexDecodeService` before generic Raydium instruction-audit preservation. - One-byte Stable Swap instruction observation support. - Coverage entries for all locally observed Stable Swap discriminants `00..0d`. - Materialization into lifecycle/liquidity/fee/admin/orderbook/trade tables when the local corpus proves a safe target. - Swap materialization from exact vault balance deltas only. - Validation SQL in `validation_sql/SQL_VALIDATION_RAYDIUM_STABLE_SWAP_0_7_52.sql`. ## Instruction surface | entry | discriminator | family | final target | local event kind | final status | |---|---:|---|---|---|---| | `initialize` | `00` | `pool_create` | `k_sol_pool_lifecycle_events` | `raydium_stable_swap.initialize` | observed/materialized when context complete | | `init_model_data` | `01` | `model_setup` | decoded-only | `raydium_stable_swap.init_model_data` | observed decoded-only / explained | | `update_model_data` | `02` | `admin_config` | `k_sol_pool_admin_events` | `raydium_stable_swap.update_model_data` | observed/materialized | | `deposit` | `03` | `liquidity_add` | `k_sol_liquidity_events` | `raydium_stable_swap.deposit` | observed/materialized | | `withdraw` | `04` | `liquidity_remove` | `k_sol_liquidity_events` | `raydium_stable_swap.withdraw` | observed/materialized | | `monitor_step` | `05` | `order_place` | `k_sol_orderbook_events` | `raydium_stable_swap.monitor_step` | observed/materialized | | `set_params` | `06` | `admin_config` | `k_sol_pool_admin_events` | `raydium_stable_swap.set_params` | observed/materialized | | `withdraw_pnl` | `07` | `fee` | `k_sol_fee_events` | `raydium_stable_swap.withdraw_pnl` | observed/materialized | | `withdraw_srm` | `08` | `fee` | `k_sol_fee_events` | `raydium_stable_swap.withdraw_srm` | observed/materialized when context complete | | `swap_base_in` | `09` | `swap` | `k_sol_trade_events` only from vault deltas | `raydium_stable_swap.swap_base_in` | observed, materialized for successful swaps with exact deltas | | `pre_initialize` | `0a` | `pool_create` | decoded-only or lifecycle when complete | `raydium_stable_swap.pre_initialize` | observed decoded-only / explained in current corpus | | `swap_base_out` | `0b` | `swap` | `k_sol_trade_events` only from vault deltas | `raydium_stable_swap.swap_base_out` | observed, materialized for successful swaps with exact deltas | | `simulate_info` | `0c` | `cpi_transport` | decoded-only | `raydium_stable_swap.simulate_info` | observed decoded-only / explained | | `admin_cancel_orders` | `0d` | `orderbook_admin` | `k_sol_orderbook_events` | `raydium_stable_swap.admin_cancel_orders` | observed/materialized when context complete | | `swap_event` | `40c6cde8260871e2` | `cpi_transport` | decoded-only | `raydium_stable_swap.swap_event` | upstream mapped, not observed in local corpus | ## Swap amount policy Stable Swap instruction arguments are retained as instruction bounds, but they are not sufficient for trade/candle materialization: ```text swap_base_in: amountInRaw = exact input argument minimumAmountOutRaw = slippage lower bound, not exact output swap_base_out: amountOutRaw = requested output argument maxAmountInRaw = slippage upper bound, not exact input ``` Therefore, `swap_base_in` and `swap_base_out` materialize as trades/candles only when exact base/quote amounts are inferred from vault balance deltas: ```text amountSource = stable_swap_vault_balance_delta ``` Instruction-bound-only swaps remain decoded-only: ```text amountSource = stable_swap_instruction_bounds_only tradeCandidate = false candleCandidate = false ``` For failed transactions the skip reasons are: ```text skipTradeReason = failed_transaction skipCandleReason = failed_transaction ``` For successful transactions where exact vault deltas cannot be proven, the expected skip reason is: ```text stable_swap_exact_amounts_unresolved ``` The final local corpus has no successful unresolved Stable Swap swap. ## Final local validation snapshot Latest confirmed local commands: ```text cargo test -p kb_lib 407 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out cargo clippy -p kb_lib --all-targets -- -D warnings ok ``` Latest replay snapshot: ```text replayed=298 decode_skipped=0 ledger_upserts=298 unsafe_ledger_rows=258 trades=290 liquidity=16 lifecycle=4 token_account=0 candle_upserts=1160 instructionObservations=5317 resetDeleted=1059 catalog=40 tokens / 59 pools / 59 pairs ``` Stable Swap swap closure: | event kind | amount source | tx status | decoded | trades | |---|---|---|---:|---:| | `raydium_stable_swap.swap_base_in` | `stable_swap_instruction_bounds_only` | failed | 27 | 0 | | `raydium_stable_swap.swap_base_in` | `stable_swap_vault_balance_delta` | success | 171 | 171 | | `raydium_stable_swap.swap_base_out` | `stable_swap_instruction_bounds_only` | failed | 2 | 0 | | `raydium_stable_swap.swap_base_out` | `stable_swap_vault_balance_delta` | success | 4 | 4 | UI smoke evidence after the vault-delta correction: ```text pair 27, timeframe 60s -> 70 candles pair 30, timeframe 60s -> 44 candles ``` ## Final invariant status Validated as clean on the local corpus: - residual `raydium_stable_swap.instruction_audit`: empty; - residual `upstream_git.instruction_match` for covered local entries: empty; - decoded-without-coverage: empty; - non-swap materialized as trade: empty; - failed transaction materialized as business trade: empty; - multi-target materialization: empty; - successful non-materialized swaps without skip reason: empty; - Stable Swap successful swaps with `stable_swap_vault_balance_delta`: `trade_count = decoded_count`; - Stable Swap instruction-bound-only swaps: failed only, `trade_count = 0`. ## Closure decision `0.7.52 raydium_stable_swap` is closed for the currently observed local corpus. The decoder has detected all locally observed Stable Swap instruction discriminants, materialized every event that can safely be materialized, and preserved non-materializable/failed events as decoded-only with explicit reasons. Future work is not a blocker for `0.7.52` and should be handled as a later tranche if a new local corpus reveals additional discriminants or a direct, reliable `swap_event` path.