<!-- file: docs/reports/PUMP_SWAP_EVENT_COVERAGE_REPORT.md -->

# PumpSwap event coverage report — `0.7.53`

## Scope

- Version cible : `0.7.53`.
- Surface unique : `pump_swap`.
- Program id unique : `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA`.
- Phasage : une version = un `program_id`.
- `raydium_pool_v4.json` reste repoussé vers la fin du phasage et ne bloque pas cette tranche.

## Sources vérifiées / à vérifier pendant la fermeture

- `kb_lib/src/constants.rs`, notamment `PUMP_SWAP_PROGRAM_ID` et `SOLSCAN_ACCOUNT_SOURCES`.
- Registre upstream local généré : `kb_lib/src/upstream_registry_generated.rs`.
- Sources Git/IDL externes disponibles : Pump public docs / IDL, Carbon, fnzero, Pinax, HODL Warden si présents dans le registre.
- IDL locale : `idls/pump_swap.pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA.json`, téléchargée depuis Solscan et versionnée dans le workspace.
- Solscan IDL du program id PumpSwap si disponible.
- Corpus local Demo3 + backfills signature/pool.
- `k_sol_dex_event_coverage_entries` après replay forcé.

Les sources Git/IDL/Solscan sont des indices. La fermeture métier exige corpus local, replay et SQL.

## Couverture locale ajoutée

Le decoder local `kb_lib/src/dex/pump_swap.rs` ne se limite plus à `buy`/`sell`. Il reconnaît maintenant les discriminants d’instruction suivants et produit un event spécialisé `pump_swap.<entry_name>`.

| Entry | Kind | Discriminator | Target attendu | Matérialisation |
|---|---|---:|---|---|
| `admin_set_coin_creator` | instruction | `f228759149606968` | admin/config | decoded specialized non-trade |
| `admin_update_token_incentives` | instruction | `d10b7357d5177ccc` | reward/admin | decoded specialized non-trade |
| `buy` | instruction | `66063d1201daebea` | trade | trade/candle seulement depuis montants exacts |
| `buy_exact_quote_in` | instruction | `c62e1552b4d9e870` | trade conditionnel | matérialisé seulement si un `BuyEvent` Anchor exact est présent (`amountSource=pump_swap_anchor_buy_event`) ; sinon decoded-only `instruction_bounds_only` avec `skipTradeReason` |
| `claim_cashback` | instruction | `253a237ebe35e4c5` | reward | decoded specialized non-trade |
| `claim_token_incentives` | instruction | `1004471ccc01281b` | reward | decoded specialized non-trade |
| `close_user_volume_accumulator` | instruction | `f945a4da9667548a` | reward | decoded specialized non-trade |
| `collect_coin_creator_fee` | instruction | `a039592ab58b2b42` | fee | decoded specialized non-trade |
| `create_config` | instruction | `c9cff3724b6f2fbd` | admin/config | decoded specialized non-trade |
| `create_pool` | instruction | `e992d18ecf6840bc` | pool lifecycle | decoded specialized non-trade |
| `deposit` | instruction | `f223c68952e1f2b6` | liquidity add | decoded specialized non-trade |
| `disable` | instruction | `b9adbb5ad80feee9` | admin/config | decoded specialized non-trade |
| `extend_account` | instruction | `ea66c2cb96483ee5` | admin/config | decoded specialized non-trade |
| `init_user_volume_accumulator` | instruction | `5e06ca73ff60e8b7` | reward | decoded specialized non-trade |
| `migrate_pool_coin_creator` | instruction | `d0089f044aaf103a` | admin/migration | decoded specialized non-trade |
| `sell` | instruction | `33e685a4017f83ad` | trade | trade/candle seulement depuis montants exacts |
| `set_coin_creator` | instruction | `d295802dbc3a4eaf` | admin/config | decoded specialized non-trade |
| `set_reserved_fee_recipients` | instruction | `6faca2e87259d58e` | admin/config | decoded specialized non-trade |
| `set_reserved_fee_recipient` | instruction | `cfbdb247a77a44b4` | admin/config | local log proof only: `Instruction: SetReservedFeeRecipient` ; absent from checked Solscan IDL raw ; decoded specialized non-trade |
| `sync_user_volume_accumulator` | instruction | `561fc057a3574fee` | reward | decoded specialized non-trade |
| `toggle_cashback_enabled` | instruction | `7367e0ffbd5956c3` | admin/config | decoded specialized non-trade |
| `toggle_mayhem_mode` | instruction | `01096fd0641fffa3` | admin/config | decoded specialized non-trade |
| `transfer_creator_fees_to_pump` | instruction | `8b348655e4e56cf1` | fee | decoded specialized non-trade |
| `transfer_creator_fees_to_pump_v2` | instruction | `01214eb921432c5c` | fee | Solscan IDL proof + local log proof: `transfer_creator_fees_to_pump_v2` / `Instruction: TransferCreatorFeesToPumpV2` ; decoded specialized non-trade |
| `update_admin` | instruction | `a1b028d53cb8b3e4` | admin/config | decoded specialized non-trade |
| `update_buyback_config` | instruction | `fbe0ab92a01a71e9` | admin/config | Solscan IDL proof + local log proof: `update_buyback_config` / `Instruction: UpdateBuybackConfig` ; decoded specialized non-trade |
| `update_fee_config` | instruction | `68b867f258976b14` | admin/config | decoded specialized non-trade |
| `withdraw` | instruction | `b712469c946da122` | liquidity remove | decoded specialized non-trade |

## Upstream Program-data events à statut explicite

Ces events sont listés dans le registre upstream. Ils doivent apparaître avec un statut explicite dans la coverage DB après sync/replay. Ils ne doivent pas créer de doublons trade/candle tant que l’instruction locale spécialisée couvre déjà le DEX effectif.

| Event | Discriminator | Statut `0.7.53` |
|---|---:|---|
| `admin_set_coin_creator_event` | `2ddc5d181961ac68` | upstream listed ; decoded-only/status explicite après replay |
| `admin_update_token_incentives_event` | `93fa6c78f71d43de` | upstream listed ; decoded-only/status explicite après replay |
| `buy_event` | `67f4521f2cf57777` | upstream listed ; audit/decoded-only to avoid duplicate trade |
| `claim_cashback_event` | `e2d6f62107f293e5` | upstream listed ; decoded-only/status explicite après replay |
| `claim_token_incentives_event` | `4facf631cd5bcee8` | upstream listed ; decoded-only/status explicite après replay |
| `close_user_volume_accumulator_event` | `929fbdac925838f4` | upstream listed ; decoded-only/status explicite après replay |
| `collect_coin_creator_fee_event` | `e8f5c2eeeada3a59` | upstream listed ; decoded-only/status explicite après replay |
| `create_config_event` | `6b34598137e25116` | upstream listed ; decoded-only/status explicite après replay |
| `create_pool_event` | `b1310cd2a076a774` | upstream listed ; decoded-only/status explicite après replay |
| `deposit_event` | `78f83d531f8e6b90` | upstream listed ; decoded-only/status explicite après replay |
| `disable_event` | `6bfdc14ce4ca1b68` | upstream listed ; decoded-only/status explicite après replay |
| `extend_account_event` | `6161d7905d92167c` | upstream listed ; decoded-only/status explicite après replay |
| `init_user_volume_accumulator_event` | `86240d48e86582d8` | upstream listed ; decoded-only/status explicite après replay |
| `migrate_pool_coin_creator_event` | `aadd52c793a5f72e` | upstream listed ; decoded-only/status explicite après replay |
| `reserved_fee_recipients_event` | `2bbcfa12dd4bbb5f` | upstream listed ; decoded-only/status explicite après replay |
| `sell_event` | `3e2f370aa503dc2a` | upstream listed ; audit/decoded-only to avoid duplicate trade |
| `set_bonding_curve_coin_creator_event` | `f2e7eb664163bdd3` | upstream listed ; decoded-only/status explicite après replay |
| `set_metaplex_coin_creator_event` | `966bc77b7ccf66e4` | upstream listed ; decoded-only/status explicite après replay |
| `sync_user_volume_accumulator_event` | `c57aa77c74515bff` | upstream listed ; decoded-only/status explicite après replay |
| `update_admin_event` | `e198ab57f63f42ea` | upstream listed ; decoded-only/status explicite après replay |
| `update_fee_config_event` | `5a1741233ef4bcd0` | upstream listed ; decoded-only/status explicite après replay |
| `withdraw_event` | `1609851aa02c47c0` | upstream listed ; decoded-only/status explicite après replay |

## Matérialisation

- `pump_swap.buy`, `pump_swap.sell` et `pump_swap.buy_exact_quote_in` peuvent alimenter `k_sol_trade_events`, mais seulement depuis des montants exacts.
- `pump_swap.buy_exact_quote_in` est matérialisé quand le log Anchor `BuyEvent` fournit `baseAmountOutRaw` et `userQuoteAmountInRaw` pour `ixName=buy_exact_quote_in`. Les rows `instruction_bounds_only` restent decoded-only avec `skipTradeReason` explicite.
- Les bornes d’instruction (`maxQuoteAmountIn`, `spendableQuoteAmountIn`, `minQuoteAmountOut`, `minBaseAmountOut`) ne sont pas considérées comme des montants exacts suffisants pour créer un trade/candle.
- La matérialisation doit passer par les résolutions exactes existantes : token transfer deltas, vault/account balance deltas ou autre source d’amount explicitement prouvée.
- Les transactions failed restent decoded-only via l’actionability `failed_transaction`.
- Les non-trades restent hors `k_sol_trade_events` et hors `k_sol_pair_candles`.

## SQL de fermeture

Le fichier dédié est :

```text
validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql
```

Les requêtes d’anomalies attendues vides couvrent :

- fallback upstream résiduel sur instruction couverte localement ;
- failed tx avec trade ;
- non-swap avec trade ;
- decoded without coverage ;
- successful non-materialized inexpliqué ;
- multi-target materialization ;
- successful swap exploitable sans trade et sans raison explicite.

## Delta post-replay `0.7.53-pump_swap-delta-1`

Le replay local a révélé trois écarts corrigés par ce delta :

- `pump_swap.toggle_cashback_enabled` était classé à la fois `reward` et `admin`; il devient admin-only pour respecter l’invariant single-target.
- `pump_swap.buy_exact_quote_in` réussi non matérialisé reçoit maintenant un `skipTradeReason` explicite et reste decoded-only tant que les montants exacts ne sont pas prouvés.
- `k_sol_instruction_observations.instruction_name` reçoit un mapping PumpSwap par discriminant pour que la requête de coverage locale ne sorte plus des noms vides. Le discriminant `e445a52e51cb9a1d` reste marqué comme transport technique Anchor self-CPI. Les trois discriminants initialement inconnus ne doivent plus sortir en `observed_unknown_*` : deux sont confirmés par le raw Solscan IDL et un reste conservé comme local-log-only.

`pump_swap.migrate_pool_coin_creator` est également forcé en admin/config, pas lifecycle, car il modifie l’attribution coin creator et ne représente pas une migration de pool échangeable.

## Delta post-replay `0.7.53-pump_swap-delta-2`

- Les trois discriminants initialement inconnus (`01214eb921432c5c`, `fbe0ab92a01a71e9`, `cfbdb247a77a44b4`) ont été provisoirement couverts decoded-only pour supprimer les gaps locaux sans inventer de métier.
- `toggle_cashback_enabled` est corrigé aussi dans la famille coverage (`admin_config`) afin de refléter la matérialisation admin-only.

## Delta post-replay `0.7.53-pump_swap-delta-4`

- Le corpus local donne maintenant le nom métier via logs Anchor : `TransferCreatorFeesToPumpV2`, `UpdateBuybackConfig`, `SetReservedFeeRecipient`.
- Ces trois discriminants deviennent des instructions locales spécialisées : `pump_swap.transfer_creator_fees_to_pump_v2`, `pump_swap.update_buyback_config`, `pump_swap.set_reserved_fee_recipient`.
- Recomparaison raw Solscan IDL : `transfer_creator_fees_to_pump_v2` et `update_buyback_config` sont présents dans l’IDL. `set_reserved_fee_recipient` n’est pas listé dans ce raw ; il est gardé sur preuve log locale, possiblement instruction historique/supprimée ou non exposée par cette version IDL.
- `transfer_creator_fees_to_pump_v2` est fee/non-trade ; `update_buyback_config` et `set_reserved_fee_recipient` sont admin/config non-trade.



## Clôture finale `0.7.53`

La tranche est clôturée après les deltas de consolidation :

- `buy_exact_quote_in` route désormais vers la matérialisation pool/pair/trade quand `amountSource=pump_swap_anchor_buy_event`;
- les montants du `BuyEvent` sont normalisés par rapport à l’ordre local de la paire pour éviter les inversions base/quote ;
- les events Anchor PumpSwap sont décodés comme events autonomes audit-only ;
- `claim_token_incentives_event` possède un test synthétique de matérialisabilité reward si un corpus réussi apparaît ;
- `sync_user_volume_accumulator_event` reste implémenté mais non observé malgré un backfill élargi sur l’instruction ;
- les tests synthétiques couvrent les instructions/events IDL non observés localement ;
- `cargo test -p kb_lib` a été validé à `421 passed / 0 failed` et clippy est OK côté utilisateur.

Résultats de validation rapportés après corpus élargi :

```text
pump_swap decoded without coverage                 = vide
pump_swap upstream fallback couvert localement      = vide
successful trade candidates sans trade              = vide
failed tx avec business trade                       = vide
non-swap matérialisé en trade                       = vide
multi-target materialization                        = vide
buy_exact_quote_in / pump_swap_anchor_buy_event     = 168 decoded / 167 trades / 1 failed tx
```

Les fichiers de surveillance à conserver sont :

- `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql` ;
- `validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql` ;
- `docs/reports/DEX_COVERAGE_GLOBAL_WATCHLIST_0_7_53.md`.
