This commit is contained in:
2026-06-14 14:25:09 +02:00
parent 38f42da970
commit 3b908b318e
100 changed files with 5873 additions and 225 deletions

View File

@@ -0,0 +1,128 @@
# DEX coverage global watchlist — `0.7.53`
## Objet
Ce rapport accompagne la clôture `0.7.53 pump_swap`. Il sépare les anomalies bloquantes des files de travail futures.
`pump_swap` est clos côté transaction/log decoder et matérialisation métier. Les lignes restantes de surveillance globale ne sont pas des erreurs PumpSwap.
## Résultat de clôture PumpSwap
Validation rapportée :
```text
cargo test -p kb_lib -> 421 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Replay élargi rapporté :
```text
1189 replayed
0 decode skipped
1189 ledger upserts
967 unsafe ledger rows
928 trades
13 liquidity
8 lifecycle
0 tokenAccount
3700 candle upserts
instructionObservations = 25724
resetDeleted = 5622
catalog = 76 tokens / 80 pools / 80 pairs
```
Checks PumpSwap attendus vides :
- decoded events sans coverage ;
- fallback `upstream_git` couvert localement ;
- successful trade candidates sans trade et sans raison explicite ;
- failed transaction matérialisée en business trade ;
- non-swap matérialisé en trade ;
- multi-target materialization.
`buy_exact_quote_in` :
```text
pump_swap_anchor_buy_event -> 168 decoded / 167 trades / 1 failed tx
instruction_bounds_only -> decoded-only, sans trade
```
## Non-régression Raydium
Les checks ciblés Raydium AMM v4 / CLMM / CPMM normalisés sont vides. Il n'y a pas de correction Raydium à inclure dans `0.7.53`.
Lecture correcte :
- `raydium_amm_v4.swap_base_in_v2` : observé et matérialisé dans le corpus courant ;
- `raydium_clmm.swap_v2` : observé et matérialisé dans le corpus courant ;
- `raydium_cpmm.swap_base_input` : observé et matérialisé dans le corpus courant ;
- les entrées `upstream_git_mapped_unverified` avec `observed_count=0` sont des entrées registry non observées, pas des régressions.
## Gaps locaux reportés
La requête globale `local decoded events without coverage` retourne des gaps Meteora connus et reportés :
```text
meteora_dlmm.swap
meteora_damm_v2.instruction_audit
meteora_damm_v2.swap
```
Décision : ne pas les corriger dans `0.7.53`. Ils seront repris dans les tranches Meteora futures.
## Backlog upstream observé
La file `upstream_git.instruction_match` indique les prochaines surfaces à prioriser. Au moment de la clôture :
| Priorité | Surface | Indice principal | Décision |
|---:|---|---|---|
| 1 | `pump_fees` | `get_fees` très fréquent | Prochaine tranche recommandée ; aucun trade/candle direct attendu. |
| 2 | `pump_fun` | creator fees, migrate, set/admin creator | Tranche launch/bonding séparée. |
| 3 | `jupiter_swap` | `route_v2`, `create_token_account`, `route` | Agrégateur/router ; éviter double-count DEX effectifs. |
| 4 | `dflow_aggregator_v4`, `onchain_labs_dex_v2` | swaps/route helpers | Surfaces secondaires après Pump/Meteora. |
| 5 | `orca_whirlpools` | faibles occurrences | À reprendre plus tard avec corpus dédié. |
## Observations non attribuées
Les observations avec `decoder_code` vide ne doivent pas être traitées comme des discriminants Anchor confirmés. Elles exigent d'abord :
1. inspection de `sample_signature` ;
2. extraction du `program_id` effectif ;
3. comparaison aux IDL locales `idls/` et aux sources Git ;
4. ajout d'un decoder ou d'un statut explicite seulement si le programme est identifié.
## Source IDL locale
Le répertoire `idls/` est désormais une source locale de savoir. Les IDL téléchargées depuis Solscan doivent être utilisées en plus des liens Git, avec la règle suivante : une IDL donne une surface possible, mais la matérialisation métier exige corpus, replay et SQL.
## Vérification `raydium_pool_v4.json`
Fichier Git vérifié : `0xfnzero/sol-parser-sdk/idls/raydium_pool_v4.json`.
Constats :
- la page GitHub annonce `3400` lignes / environ `101 KB` ;
- le fichier expose notamment `swapBaseIn`, `addLiquidity` et des comptes OpenBook/Serum (`OpenBookMarket`, `OpenBookBids`, `OpenBookAsks`, etc.) ;
- la chaîne du program id AMM v4 `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` n'apparaît pas dans la page GitHub consultée ;
- aucun fichier local `idls/raydium_*.json` ne porte le nom `raydium_pool_v4` ;
- les fichiers Raydium locaux présents sont `raydium_clmm`, `raydium_cpmm`, `raydium_launchlab` et `raydium_lock`.
Table locale :
| Fichier local | Name IDL | Address IDL | Taille | SHA-256 |
|---|---|---|---:|---|
| `idls/raydium_clmm.CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK.json` | `raydium_clmm` | `CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK` | 86240 | `d3f265adc9e4d7b1a28641444800a60bcdeb921ef136855fe8dea4532afa18bd` |
| `idls/raydium_cpmm.CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C.json` | `raydium_cp_swap` | `CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C` | 32066 | `5b709dfe7b0df67c9e29655307ae877244d3bb8022056ee01c754f0e36264d9c` |
| `idls/raydium_launchlab.LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj.json` | `raydium_launchpad` | `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj` | 68052 | `c1465a10f38912413f55f04a68536c989992add1b3d48cba86dca97212a482da` |
| `idls/raydium_lock.LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE.json` | `raydium_liquidity_locking` | absent | 10621 | `da45fd5eaf726e5e2ead7280c04588ebd4224d203304cdc8217b012b8130e1f1` |
Décision : `raydium_pool_v4.json` ne correspond à aucun fichier JSON local actuel. Il reste une source annexe d'audit AMM v4/strategy/wrapper à traiter plus tard, sans bloquer `0.7.53`.
## SQL associé
Voir :
```text
validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql
```

View File

@@ -0,0 +1,166 @@
# 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 dinstruction 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 linstruction 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 dinstruction (`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 damount explicitement prouvée.
- Les transactions failed restent decoded-only via lactionability `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 danomalies 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 linvariant 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 lattribution 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 lIDL. `set_reserved_fee_recipient` nest 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 à lordre 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 linstruction ;
- 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`.