This commit is contained in:
2026-06-17 16:06:09 +02:00
parent be12f5810b
commit 319be14aa6
37 changed files with 7129 additions and 363 deletions

View File

@@ -2,6 +2,21 @@
# Database Event Model Review — `khadhroony-bobobot` `0.7.47-1FE5`
## Note `0.7.56` — modèle fee parent + amount legs
`0.7.56` ajoute `k_sol_fee_event_amounts` comme table enfant de `k_sol_fee_events`. Cette table est obligatoire dès qu'un event fee porte plusieurs montants, plusieurs mints ou plusieurs destinations. Le parent `k_sol_fee_events` reste l'ancre logique liée au `decoded_event_id`; les legs portent `leg_index`, `token_mint`, `amount_raw`, comptes source/destination et `amount_source`.
Invariants :
- tout parent fee avec `fee_token_mint + fee_amount_raw` doit avoir un leg scalaire automatique ;
- un fee multi-leg/multi-mint ne doit pas agréger artificiellement le parent ;
- les replays doivent supprimer/remplacer les legs avec le parent ;
- les transactions failed restent audit-only ;
- la recovery `allowlisted_inner_spl_transfer` est strictement allowlistée et ne s'applique pas par défaut aux futurs decoders.
Le contrôle standard `parent scalar without leg` doit être vide sur toute base de validation. Voir `docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md`.
## Conclusion courte
La base actuelle est **suffisante pour continuer le décodage exhaustif en audit-only**, parce que `k_sol_dex_decoded_events` garde les events décodés avec `payload_json`.

View File

@@ -1,15 +1,26 @@
<!-- file: docs/DEX_DECODER_MATRIX.md -->
# DEX Decoder Matrix — `khadhroony-bobobot` `0.7.55 pump_fees closed`
# DEX Decoder Matrix — `khadhroony-bobobot` `0.7.56 meteora_dbc closed`
## Note `0.7.56 closed` — Meteora DBC clôturé, DLMM ensuite
La tranche `0.7.56` ferme `meteora_dbc` / `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN` depuis l'IDL locale `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json`.
Le decoder local couvre les `28` instructions et les `23` events Anchor IDL. Les trades/candles ne sont produits que depuis `swap` / `swap2` avec montants et mints fiables. Les migrations, lockers, lifecycle, admin/config et fees sont matérialisés quand le contexte est fiable ; sinon ils restent decoded-only/audit-only avec raison explicite. Les transactions failed restent audit-only.
Le modèle fee est maintenant transversal : `k_sol_fee_events` reste le parent, `k_sol_fee_event_amounts` porte les legs. Les parents fees scalaires créent automatiquement un leg ; les fees multi-leg/multi-mint n'agrègent pas artificiellement le parent. La recovery `allowlisted_inner_spl_transfer` est allowlistée et ne s'applique jamais par défaut à un futur decoder.
La prochaine tranche programmée est `0.7.57 meteora_dlmm` avec objectif full decode + full materialization sur `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo`.
## Note `0.7.55 closed` — Pump Fees clôturé, Meteora DBC ensuite
La tranche `0.7.55` ferme `pump_fees` comme surface fee/config/accounting. Le decoder local couvre les `29` instructions et `20` events Anchor de l'IDL locale, avec tests synthétiques pour les Anchor events IDL non observés. Les transactions failed restent audit-only, `get_fees` reste decoded-only, et aucun trade/candle direct n'est créé.
Deux discriminators Solscan non présents dans l'IDL locale restent conservés en coverage comme surfaces futures : `revoke_fee_sharing_authority_event` (`7217653c0ebe993e`) et `transfer_fee_sharing_authority_event` (`7c8fc6f54db808ec`).
La prochaine tranche programmée est `0.7.56 meteora_dbc`.
La tranche suivante après `0.7.55` a été `0.7.56 meteora_dbc`, désormais clôturée ; la prochaine tranche courante est `0.7.57 meteora_dlmm`.
## Note `0.7.54 closed` — Pump.fun clôturé
@@ -69,8 +80,8 @@ Cette matrice complète `kb_lib/src/dex_support_matrix.rs`. Elle documente **ce
| 7 | `pump_swap` | `supported / 0.7.53 closed` | `buy`, `sell` + `buy_exact_quote_in` matérialisable via `BuyEvent` exact ; instructions non-trade spécialisées : liquidity, fee/creator fee, admin/config, cashback/token incentives, volume accumulator ; events Anchor autonomes audit-only. | Trades/candles uniquement depuis montants exacts ; failed tx decoded-only ; `instruction_bounds_only` reste decoded-only ; tests synthétiques IDL et SQL global ajoutés. |
| 8 | `pump_fun` | `supported / 0.7.54 closed` | Surface launch/bonding/migration Pump.fun couverte localement ; trades directs et `trade_event` canonique validés. | Ne rouvrir que pour bug prouvé ou changement externe. |
| 9 | `pump_fees` | `supported / 0.7.55 closed` | Surface fee/config/accounting couverte localement : `29` instructions, `20` events Anchor, fee/reward/admin/lifecycle, tests synthétiques Anchor IDL non observés, failed tx audit-only. | Aucun trade/candle direct ; conserver les deux discriminators Solscan hors IDL comme futures surfaces non observées. |
| 10 | `meteora_dbc` | `partial / 0.7.56 planned` | Swaps/instruction audits observés ; Demo3 donne du corpus. | Couverture complète DBC : launch/bonding curve, swap, migration, config/admin, fees ; matérialiser seulement ce qui est prouvé. |
| 11 | `meteora_dlmm` | `supported / 0.7.57 parity` | Couverture avancée validée en `0.7.45` : swaps, liquidity, positions, lifecycle, fees ; non-trade matérialisé. | Résoudre les audits résiduels non mappés ; comparer Carbon/IDL pour events rewards/admin restants ; revalidation base neuve. |
| 10 | `meteora_dbc` | `supported / closed 0.7.56` | Decoder local maximal : `28` instructions, `23` events Anchor, swaps `swap/swap2`, lifecycle/admin/fees, `k_sol_fee_event_amounts`, validation SQL propre. | Ne pas rouvrir sauf bug prouvé ; préserver la policy fee parent+legs et la recovery allowlistée. |
| 11 | `meteora_dlmm` | `next / 0.7.57 full decode` | Couverture partielle historique validée en `0.7.45`; IDL locale `76` instructions / `30` events Anchor. | Reprendre depuis base neuve : full decode, full materialization fiable, fees/rewards via `fee_event_amounts`, no double-count avec events Anchor. |
| 12 | `meteora_damm_v1` | `supported / 0.7.58 parity` | Couverture `0.7.46` : swap, create_pool, add/remove liquidity, claim_fee, create_lock_escrow, lock_liquidity. | Vérifier les surfaces upstream non observées ; améliorer rattachement pool/pair pour remove_liquidity non matérialisés ; revalidation stricte. |
| 13 | `meteora_damm_v2` | `partial / 0.7.59 planned` | `swap`, `instruction_audit`, registry/discriminants et corpus Demo3 existent. | Couvrir tous les events Carbon/source : create pool, liquidity, fees, dynamic config, admin ; déterminer actionability des swaps ; matérialiser si montants fiables. |
| 14 | `phoenix_v1` | `audit-only / 0.7.60 planned` | Decoder local audit-only ; `log_audit`, order place/cancel, withdraw ; parsing strict `0x0f`; events `Reduce`, `Place`, `TimeInForce` observés ; `trade_count=0`. | Terminer tous les events Git : `Fill`, `FillSummary`, `Fee`, `Evict`, `ExpiredOrder`, etc. ; ajouter counts/flags audit ; seulement ensuite étudier trade materialization. |
@@ -325,3 +336,18 @@ La tranche a été validée sur base SQLite dédiée : tous les discriminants `0
| Decoder | Program id | Statut | Source discriminants | Couverture locale | Règles métier |
|---|---|---:|---|---|---|
| `pump_fees` | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | supported / `0.7.55 closed` | `idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json` + Carbon partiel + Solscan discriminators | `29` instructions et `20` events Anchor couverts ; tests synthétiques pour les Anchor events IDL non observés ; replay final propre ; watchlist `pump_fees` vide | Aucun trade/candle direct ; `get_fees` decoded-only ; social claim vers reward ; donation/buyback vers fee ; config/authority/tier/admin vers admin/lifecycle ; failed tx audit-only ; deux events Solscan hors IDL conservés non observés. |
## 0.7.56 — Meteora DBC clôturé
| Decoder | Program id | Statut | Source locale | Couverture | Décision métier |
|---|---|---|---|---|---|
| `meteora_dbc` | `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN` | `supported / closed 0.7.56` | `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json` | `28` instructions IDL + `23` events Anchor IDL, tests synthétiques et validation SQL dédiée | `swap`/`swap2` seuls vers trade/candle direct ; lifecycle/admin/fee selon contexte ; fees parent+legs ; failed tx audit-only. |
Validation finale : `446` tests, clippy OK, `480 replayed`, `264 trades`, `1 liquidity`, `122 lifecycle`, `1056 candles`, `89` parents fee DBC, `96` fee amount legs, invariants SQL propres.
## 0.7.57 — Meteora DLMM prochain
| Decoder | Program id | Statut | Source locale | Couverture attendue | Décision métier |
|---|---|---|---|---|---|
| `meteora_dlmm` | `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo` | `next / full decode + full materialization` | `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` | `76` instructions IDL + `30` events Anchor IDL | Swaps/exact-out, liquidity/bin/position, fees/rewards/admin/config, limit order events ; no duplicate trade/candle ; `fee_event_amounts` obligatoire pour fees. |

View File

@@ -309,3 +309,34 @@ Programme : `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ`. Source locale priorit
Invariants propres : fallback `pump_fees` vide, decoded sans coverage vide, successful non-materialized sans skip/policy vide, failed tx matérialisée vide, multi-target vide, anti-trade/candle direct vide, watchlist globale sans `pump_fees`.
## 0.7.56 — Meteora DBC clôturé
Programme : `dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN`. Source locale prioritaire : `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json`.
| Groupe | Entrées | Famille | Cible DB | Local event kind | Décision finale |
|---|---|---|---|---|---|
| swaps | `swap`, `swap2` | swap | `k_sol_trade_events` + candles | `meteora_dbc.swap`, `meteora_dbc.swap2` | Matérialisés seulement avec montants et mints base/quote fiables ; `swap2` validé via transferts CPI/amount inference. |
| virtual pool init | `initialize_virtual_pool_with_spl_token`, `initialize_virtual_pool_with_token2022`, `EvtInitializePool` | pool_create | `k_sol_pool_lifecycle_events` + catalog si contexte complet | `meteora_dbc.initialize_virtual_pool_with_*`, `meteora_dbc.evt_initialize_pool_event` | Lifecycle/catalog prudent ; failed tx audit-only. |
| migration / lockers | `migrate_meteora_damm*`, `migration_damm_v2*`, `create_locker`, `EvtCurveComplete` | migration / lifecycle | `k_sol_pool_lifecycle_events` | `meteora_dbc.migrate_*`, `meteora_dbc.migration_*`, `meteora_dbc.create_locker` | Lifecycle, pas liquidity artificielle pour LP claim/lock ; metadata-only decoded-only si contexte insuffisant. |
| fees/surplus/leftover | `claim_*fee*`, `withdraw_migration_fee`, `zap_protocol_fee`, `*_withdraw_surplus`, `withdraw_leftover`, events Anchor fee | fee | `k_sol_fee_events` + `k_sol_fee_event_amounts` | `meteora_dbc.*fee*`, `meteora_dbc.*surplus*`, `meteora_dbc.*leftover*` | Montants réels depuis CPI SPL ou lamport delta ; maxima d'instruction refusés ; multi-leg/multi-mint dans `k_sol_fee_event_amounts`. |
| admin/config/metadata/operator | `create_config`, `create_operator_account`, `close_*operator*`, metadata, `transfer_pool_creator`, config events | admin_config | `k_sol_pool_admin_events` ou decoded-only | `meteora_dbc.*config*`, `meteora_dbc.*operator*`, `meteora_dbc.*metadata*`, `meteora_dbc.transfer_pool_creator` | Admin si compte/acteur fiables ; payload metadata générique decoded-only avec raison. |
| Anchor swap events | `EvtSwap`, `EvtSwap2` | swap/audit | decoded-only sauf corrélation sûre | `meteora_dbc.evt_swap_event`, `meteora_dbc.evt_swap2_event` | Les events portent des montants mais pas toujours le contexte mint/pair ; pas de double-count avec l'instruction swap matérialisée. |
Validation finale DBC : `89` parents fee, `96` legs fee amount, aucun parent scalaire sans leg, aucun leg orphelin, aucun decoded event local sans coverage, aucun failed tx matérialisé, aucun multi-target, aucun non-swap vers trade/candle.
## 0.7.57 — Meteora DLMM à reprendre
Programme : `LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo`. Source locale : `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json`.
| Groupe | Entrées IDL | Famille | Cible DB attendue | Décision à valider |
|---|---|---|---|---|
| swaps | `swap`, `swap2`, `swap_exact_out*`, `swap_with_price_impact*`, `Swap`, `Swap2Evt` | swap | `k_sol_trade_events` + candles | Montants exécutés uniquement ; éviter double-count instruction/event. |
| pools / bins | `initialize_*lb_pair*`, `initialize_bin_array*`, `close_bin_array`, `LbPairCreate` | lifecycle | `k_sol_pool_lifecycle_events`, catalog/pair | Catalog si comptes pool/mints/config fiables. |
| liquidity / positions | `add_liquidity*`, `remove_liquidity*`, `remove_all_liquidity`, `rebalance_liquidity`, position create/close/update events | liquidity/lifecycle | `k_sol_liquidity_events`, `k_sol_pool_lifecycle_events` | Montants x/y/bin/liquidity fiables ; sinon skip reason. |
| fees | `claim_fee*`, `withdraw_protocol_fee`, `zap_protocol_fee`, `ClaimFee*`, `CompositionFee` | fee | `k_sol_fee_events` + `k_sol_fee_event_amounts` | Utiliser le socle fee parent+legs ; policy recovery explicite, non globale. |
| rewards | `initialize_reward`, `fund_reward`, `claim_reward*`, `withdraw_ineligible_reward`, reward events | reward | `k_sol_reward_events` | Montant/mint/récompense fiable uniquement. |
| admin/config | fee parameters, pair status, activation, operator, token badge, preset parameter | admin_config | `k_sol_pool_admin_events` ou decoded-only | Matérialiser si acteur/compte cible fiable. |
| limit/order events | place/cancel/close limit order events | orderbook/audit | `k_sol_orderbook_events` si modèle fiable | Pas de candle directe sans fill exact. |

View File

@@ -0,0 +1,51 @@
<!-- file: docs/VALIDATION_STATUS_0_7_56_FINAL.md -->
# Validation Status — `0.7.56 meteora_dbc final`
## Build
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
## Replay final DBC
```text
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
0 tokenAccount
1056 candle upserts
instructionObservations = 7167
resetDeleted = 3583
catalog = 86 tokens / 60 pools / 60 pairs
```
## Fee model final DBC
```text
k_sol_fee_events meteora_dbc = 89 parents
k_sol_fee_event_amounts meteora_dbc = 96 legs
parent scalar without leg = empty
orphan fee amount legs = empty
allowlisted recovery on DBC = empty by design
```
## Cross-base fee recovery checks
| Base | Result |
|---|---|
| `meteora_dbc` | stable, no regression, 89/96 fee parent/legs. |
| `raydium_launchpad` | allowlisted CPI recovery enriched all observed claim/collect fee parents in tested corpus. |
| `raydium_cpmm` | creator fee recovered; fund/protocol fee explicit no-transfer in tested corpus. |
| `pump_swap` | coin creator fee mostly recovered; zero/no-transfer cases explicit. |
| `pump_fees` | donation and sweep buyback recovered when CPI SPL transfers are present. |
## Closure decision
`0.7.56 meteora_dbc` is closed. Next tranche: `0.7.57 meteora_dlmm` full decode + full materialization.

View File

@@ -1,3 +1,5 @@
<!-- file: docs/prompts/PROMPT_0_7_56_METEORA_DBC.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.56 — meteora_dbc
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture technique de `0.7.55 pump_fees`.
@@ -210,7 +212,7 @@ Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
```text
khadhroony-bobobot-v0.7.56-meteora_dbc-delta-N-files.zip
khadhroony-bobobot-v0.7.56-meteora_dbc-delta-pre.xxx.zip
```
Inclure dans chaque livraison : résumé des changements, liste exacte des fichiers modifiés, commandes `cargo fmt`, `cargo test -p kb_lib`, `cargo clippy -p kb_lib --all-targets -- -D warnings`, replay recommandé, SQL à exécuter et résultats attendus.

View File

@@ -0,0 +1,457 @@
<!-- file: docs/prompts/PROMPT_0_7_57_METEORA_DLMM_FULL_DECODE_MATERIALIZATION.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.57` — `meteora_dlmm` full decode / full materialization
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture de `0.7.56 meteora_dbc`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après application des docs `0.7.56 final`.
Fichiers à lire en priorité :
- `README.md` ;
- `ROADMAP.md` ;
- `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md` ;
- `docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md` ;
- `docs/VALIDATION_STATUS_0_7_56_FINAL.md` ;
- `validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql` ;
- `validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql` ;
- `idls/**`, en particulier `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` ;
- `kb_lib/src/dex/meteora_dlmm.rs` ;
- `kb_lib/src/non_trade_event_materialization.rs` ;
- `kb_lib/src/db/queries/fee_event_amount.rs`.
Ne pas supposer que l'ancien support `0.7.45 meteora_dlmm` est suffisant : il était partiel. `0.7.57` doit viser la parité IDL/corpus complète.
## 2. État validé avant cette version
`0.7.56 meteora_dbc` est clos.
Build final :
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Replay final DBC :
```text
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
1056 candle upserts
instructionObservations = 7167
catalog = 86 tokens / 60 pools / 60 pairs
```
Socle fee final :
```text
k_sol_fee_events meteora_dbc = 89 parents
k_sol_fee_event_amounts meteora_dbc = 96 legs
parent scalar without leg = empty
orphan fee amount legs = empty
```
Règles fee à préserver :
- parent fee scalaire -> leg `k_sol_fee_event_amounts` automatique ;
- fee multi-leg/multi-mint -> parent sans agrégation artificielle, legs explicites ;
- pas de montant depuis `maxAmount`, `u64::MAX`, bornes ou limites de claim ;
- recovery CPI SPL générique uniquement si policy/allowlist explicite ;
- aucun futur decoder ne doit hériter de `allowlisted_inner_spl_transfer` par défaut.
## 3. Objectif de `0.7.57 meteora_dlmm`
Program id cible :
```text
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
```
IDL locale prioritaire :
```text
idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json
```
Nom IDL : `lb_clmm`.
Surface IDL :
```text
76 instructions
30 events Anchor
12 accounts
```
Objectif : **full decode + full materialization**.
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite. les instructions/events/anchors/discriminator non observés aprés backfill sur une base de donnée vierge devront avoir des tests syntetiques.
## 4. Méthode obligatoire
Créer une nouvelle DB dédiée à `0.7.57 meteora_dlmm`.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis : refresh catalog, replay local, SQL validation, note des compteurs.
Ne pas rouvrir `meteora_dbc`, Pump ou Raydium sauf bug prouvé par SQL.
## 5. Sources à comparer
Comparer au minimum :
- IDL locale `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` ;
- Carbon Meteora DLMM decoder ;
- Pinax/Substreams Solana IDLs ;
- Solana Streamer / sol-parser-sdk si DLMM y apparaît ;
- code local historique `kb_lib/src/dex/meteora_dlmm.rs` ;
- coverage existante `k_sol_dex_event_coverage_entries` ;
- corpus SQLite neuf ;
- anciens rapports `0.7.45` et matrices pour comprendre ce qui était déjà validé.
## 6. Checklist d'instructions IDL à inventorier
| Instruction | Discriminator hex |
|---|---|
| `add_liquidity` | `b59d59438fb63448` |
| `add_liquidity2` | `e4a24e1c46db7473` |
| `add_liquidity_by_strategy` | `0703967f94283dc8` |
| `add_liquidity_by_strategy2` | `03dd95da6f8d76d5` |
| `add_liquidity_by_strategy_one_side` | `2905eeaf64e106cd` |
| `add_liquidity_by_weight` | `1c8cee63e7a21595` |
| `add_liquidity_by_weight2` | `d13b3f5b6fc899e4` |
| `add_liquidity_one_side` | `5e9b6797465fdca5` |
| `add_liquidity_one_side_precise` | `a1c26754ab47fa9a` |
| `add_liquidity_one_side_precise2` | `2133a3c975627de7` |
| `cancel_limit_order` | `849c841f4328e861` |
| `claim_fee` | `a9204f8988e84689` |
| `claim_fee2` | `70bf65ab1c907fbb` |
| `claim_reward` | `955fb5f25e5a9ea2` |
| `claim_reward2` | `be037f77b2579db7` |
| `close_bin_array` | `44ae5850b5cc13e0` |
| `close_claim_fee_operator_account` | `b8d5581fb3658224` |
| `close_limit_order_if_empty` | `397c249b7ef95dab` |
| `close_operator_account` | `ab09d54a7817031d` |
| `close_position` | `7b86510031446262` |
| `close_position2` | `ae5a2373ba2893e2` |
| `close_position_if_empty` | `3b7cd4765b986e9d` |
| `close_preset_parameter` | `04949164861ab53d` |
| `close_preset_parameter2` | `27195f6b7411731c` |
| `close_token_badge` | `6c92566eb3fe0a68` |
| `create_operator_account` | `dd40f695f099e5a3` |
| `decrease_position_length` | `c2db882019606925` |
| `for_idl_type_generation_do_not_call` | `b46945505f32496c` |
| `fund_reward` | `bc32f9a55d97263f` |
| `go_to_a_bin` | `9248aee028fd54ae` |
| `increase_oracle_length` | `be3d7d57674f9ead` |
| `increase_position_length` | `505375d3420d2195` |
| `increase_position_length2` | `ffd2cc477389e171` |
| `initialize_bin_array` | `235613b94ed44bd3` |
| `initialize_bin_array_bitmap_extension` | `2f9de2b40cf02147` |
| `initialize_customizable_permissionless_lb_pair` | `2e2729876fb7c840` |
| `initialize_customizable_permissionless_lb_pair2` | `f349817e3313f16b` |
| `initialize_lb_pair` | `2d9aedd2dd0fa65c` |
| `initialize_lb_pair2` | `493b2478ed536cc6` |
| `initialize_permission_lb_pair` | `6c66d555fb033515` |
| `initialize_position` | `dbc0ea47bebf6650` |
| `initialize_position2` | `8f13f291d50f6873` |
| `initialize_position_by_operator` | `fbbdbef475fe2394` |
| `initialize_position_pda` | `2e527d92558de499` |
| `initialize_preset_parameter` | `42bc47d3626d0eba` |
| `initialize_reward` | `5f87c0c4f281e644` |
| `initialize_token_badge` | `fd4dcd5f1be059df` |
| `place_limit_order` | `6cb021ba92e501c5` |
| `rebalance_liquidity` | `5c04b0c177b95309` |
| `remove_all_liquidity` | `0a333d2370691855` |
| `remove_liquidity` | `5055d14818ceb16c` |
| `remove_liquidity2` | `e6d7527ff165e392` |
| `remove_liquidity_by_range` | `1a526698f04a691a` |
| `remove_liquidity_by_range2` | `cc02c391359191cd` |
| `set_activation_point` | `5bf90fa51a81fe7d` |
| `set_pair_status` | `43f8e7899a95d9ae` |
| `set_pair_status_permissionless` | `4e3b98d346b72ed0` |
| `set_permissionless_operation_bits` | `543acb8ba351beba` |
| `set_pre_activation_duration` | `a53dc9f4829f1664` |
| `set_pre_activation_swap_address` | `398b2f7bd850df0a` |
| `swap` | `f8c69e91e17587c8` |
| `swap2` | `414b3f4ceb5b5b88` |
| `swap_exact_out` | `fa49652126cf4bb8` |
| `swap_exact_out2` | `2bd7f784893cf351` |
| `swap_with_price_impact` | `38ade6d0ade49ccd` |
| `swap_with_price_impact2` | `4a62c0d6b1334b33` |
| `update_base_fee_parameters` | `4ba8dfa110c3032f` |
| `update_dynamic_fee_parameters` | `5ca12ef6ffbd1616` |
| `update_fees_and_reward2` | `208eb89a6741b858` |
| `update_fees_and_rewards` | `9ae6fa0decd14bdf` |
| `update_position_operator` | `cab8678fb4bf74d9` |
| `update_reward_duration` | `8aaec4a9d5ebfe6b` |
| `update_reward_funder` | `d31c3020d7a02317` |
| `withdraw_ineligible_reward` | `94ce2ac3f7316708` |
| `withdraw_protocol_fee` | `9ec99ebd215da267` |
| `zap_protocol_fee` | `d59bbb2238b65bf0` |
## 7. Checklist d'events Anchor IDL à inventorier
| Event | Discriminator hex |
|---|---|
| `AddLiquidity` | `1f5e7d5ae3343dba` |
| `CancelLimitOrderEvt` | `83eac285090ebdd1` |
| `ClaimFee` | `4b7a9a308c4a7ba3` |
| `ClaimFee2` | `e8abf2613a4d232d` |
| `ClaimReward` | `947486cc16ab555f` |
| `ClaimReward2` | `1b8ff421502b6e92` |
| `CloseLimitOrderEvt` | `8e87084c5c3f7653` |
| `CompositionFee` | `80977b6a1166718e` |
| `DecreasePositionLength` | `3476eb55aca90f80` |
| `DynamicFeeParameterUpdate` | `5858b287c2925bf3` |
| `FeeParameterUpdate` | `304cf17590d7f22c` |
| `FundReward` | `f6e43a8291aa4fcc` |
| `GoToABin` | `3b8a4c448a83b043` |
| `IncreaseObservation` | `63f91179a69ccfd7` |
| `IncreasePositionLength` | `9def2acc1e38df2e` |
| `InitializeReward` | `d399583e953cb146` |
| `LbPairCreate` | `b94afc7d1bd7bc6f` |
| `PlaceLimitOrderEvt` | `2b4f1ba9f41ce13f` |
| `PositionClose` | `ffc4106b1cca3580` |
| `PositionCreate` | `908efc549d352579` |
| `Rebalancing` | `006d75b33d5bc7c8` |
| `RemoveLiquidity` | `74f461e8671f983a` |
| `SetPositionPermissionlessOperationBitsEvt` | `c3e593f51d7d30a8` |
| `Swap` | `516ce3becdd00ac4` |
| `Swap2Evt` | `2e7452d7941b544d` |
| `UpdatePositionLockReleasePoint` | `85d642e0400c07bf` |
| `UpdatePositionOperator` | `277330ccf62f4239` |
| `UpdateRewardDuration` | `dff5e099311da3ac` |
| `UpdateRewardFunder` | `e0b2ae4afca555b4` |
| `WithdrawIneligibleReward` | `e7bd419566d79af4` |
## 8. Matérialisation attendue
### Swaps
Cibles :
```text
swap
swap2
swap_exact_out
swap_exact_out2
swap_with_price_impact
swap_with_price_impact2
Swap
Swap2Evt
```
Décision :
- `k_sol_trade_events` + candles uniquement si montants exécutés, sens, pool, token X/Y et mints sont fiables ;
- les events Anchor swap ne doivent pas double-compter une instruction swap déjà matérialisée ;
- exact-out et price-impact ne doivent pas utiliser des bornes comme montants exécutés ;
- si le contexte n'est pas fiable : `skipTradeReason` + `skipCandleReason`.
### Liquidity / bins / positions
Cibles :
```text
add_liquidity*
remove_liquidity*
remove_all_liquidity
rebalance_liquidity
initialize_position*
close_position*
position create/close/update events
initialize_bin_array*
close_bin_array
```
Décision :
- `k_sol_liquidity_events` quand les montants token X/Y, pool, position et acteur sont fiables ;
- lifecycle pour création/fermeture position/bin/pair ;
- skip reason explicite pour position/bin sans montants exploitables.
### Pools / catalog
Cibles :
```text
initialize_lb_pair
initialize_lb_pair2
initialize_permission_lb_pair
initialize_customizable_permissionless_lb_pair
initialize_customizable_permissionless_lb_pair2
LbPairCreate
```
Décision : lifecycle/catalog/pool/pair si mints X/Y, pool, config/preset et comptes vault sont fiables.
### Fees
Cibles :
```text
claim_fee
claim_fee2
withdraw_protocol_fee
zap_protocol_fee
ClaimFee
ClaimFee2
CompositionFee
```
Décision :
- `k_sol_fee_events` + `k_sol_fee_event_amounts` obligatoires si montant/mint fiable ;
- utiliser parent scalaire + leg automatique pour mono-fee ;
- utiliser multi-leg sans agrégation parent si plusieurs mints/composants ;
- ne pas confondre composition fee inclus dans swap/liquidity avec claim fee matérialisable ;
- déclarer explicitement toute policy de recovery ; ne pas ajouter DLMM à l'allowlist générique sans preuve et tests.
### Rewards
Cibles :
```text
initialize_reward
fund_reward
claim_reward
claim_reward2
withdraw_ineligible_reward
ClaimReward
ClaimReward2
FundReward
InitializeReward
WithdrawIneligibleReward
```
Décision : `k_sol_reward_events` si montant/mint/reward index fiables ; decoded-only sinon.
### Admin/config/status/operator/token badge
Cibles :
```text
update_base_fee_parameters
update_dynamic_fee_parameters
update_fees_and_rewards
update_fees_and_reward2
set_pair_status
set_pair_status_permissionless
set_activation_point
set_pre_activation_duration
set_pre_activation_swap_address
set_permissionless_operation_bits
create_operator_account
close_operator_account
close_claim_fee_operator_account
initialize_token_badge
close_token_badge
initialize_preset_parameter
close_preset_parameter
close_preset_parameter2
```
Décision : `k_sol_pool_admin_events` si acteur/cible fiables ; decoded-only avec raison sinon.
### Limit orders / orderbook-like events
Cibles :
```text
place_limit_order
cancel_limit_order
close_limit_order_if_empty
PlaceLimitOrderEvt
CancelLimitOrderEvt
CloseLimitOrderEvt
```
Décision : `k_sol_orderbook_events` si sémantique fiable ; pas de trade/candle sans fill exact.
## 9. SQL de validation attendu
Créer/mettre à jour :
```text
validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql
```
Le fichier doit vérifier au minimum :
1. fallback upstream DLMM ;
2. instruction observations DLMM ;
3. coverage DLMM ;
4. decoded DLMM sans coverage ;
5. successful non-materialized sans skip reason ;
6. failed tx materialization ;
7. multi-target materialization ;
8. trade/candle sur non-swap ;
9. fee parent/legs ;
10. orphan fee legs ;
11. reward/fee separation ;
12. orderbook/limit-order sans double-count ;
13. watchlist globale.
## 10. Invariants de fermeture
`0.7.57 meteora_dlmm` ne peut être clôturé que si :
- les `76` instructions et `30` events Anchor IDL sont dans la coverage ou explicitement non observés avec tests synthétiques ;
- aucun fallback upstream DLMM ne reste pour les entrées couvertes localement ;
- aucun decoded DLMM local sans coverage ;
- aucune tx failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ou policy explicite ;
- aucun non-swap ne produit trade/candle ;
- aucun fee parent scalaire sans leg ;
- aucun leg fee orphelin ;
- aucun reward n'est classé fee par défaut ;
- aucun limit/order event ne produit une candle sans fill exact ;
- la watchlist globale ne contient plus de backlog dominant `meteora_dlmm`.
## 11. Contraintes de code à respecter
- Rust 2024 ;
- async-first ;
- tracing obligatoire ;
- pas de `?`, pas de `unwrap/expect` en production ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod` : utiliser `mod` + `pub use` ;
- imports seulement pour les traits ;
- `#![deny(unreachable_pub)]`, `#![warn(missing_docs)]` ;
- tests offline ;
- pas de macro DB/coverage ;
- après modification DB : re-exports `kb_lib/src/db.rs` et `kb_lib/src/lib.rs` ;
- après modification decoder : vérifier `kb_lib/src/dex.rs`, `kb_lib/src/lib.rs`, coverage et tests synthétiques.
## 12. Format de livraison attendu
Livrer des deltas successifs :
```text
khadhroony-bobobot-v0.7.57-meteora_dlmm-delta-pre.xxx.zip
```
Chaque réponse doit indiquer : fichiers modifiés, raisons, tests à lancer, SQL à exécuter, résultat attendu, et risques éventuels.

View File

@@ -0,0 +1,151 @@
<!-- file: docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md -->
# Note technique — `k_sol_fee_event_amounts` et policy fees — `0.7.56`
## Objectif
La table `k_sol_fee_events` était suffisante pour un fee mono-montant, mais insuffisante pour les cas multi-mint, multi-destination ou multi-composant. `0.7.56` ajoute donc `k_sol_fee_event_amounts` comme table de legs rattachée au parent fee.
## Modèle
```text
k_sol_fee_events
id
transaction_id
decoded_event_id
fee_token_mint nullable / vide si multi-leg
fee_amount_raw nullable / vide si multi-leg
payload_json
k_sol_fee_event_amounts
id
fee_event_id
transaction_id
decoded_event_id
leg_index
fee_component_kind
token_mint
amount_raw
source_account
destination_account
amount_source
payload_json
```
## Règles invariantes
1. Un parent fee scalaire avec `fee_token_mint + fee_amount_raw` doit toujours avoir un leg `0`.
2. Un parent multi-leg ou multi-mint ne doit pas agréger artificiellement ses montants dans le parent.
3. Les legs doivent pointer vers le même `transaction_id` et `decoded_event_id` que le parent.
4. Les legs doivent être supprimés/remplacés lors du replay/cleanup parent.
5. Les transactions failed ne doivent pas créer de parent ou leg fee métier.
6. Les bornes d'instruction (`maxAmount`, `minAmount`, `u64::MAX`) ne sont pas des montants exécutés.
## Sources de montant acceptées
| `amount_source` | Usage |
|---|---|
| `parent_fee_event_amount` | Leg généré automatiquement depuis un parent scalaire déjà fiable. |
| `fee_event_amounts` | Source explicite reconstruite par un matérialisateur spécialisé. |
| `inner_spl_transfer` | CPI SPL vérifié dans un matérialisateur spécialisé. |
| `lamport_balance_delta` | Delta lamports prouvé et contextualisé. |
| `allowlisted_inner_spl_transfer` | Recovery générique mais strictement allowlistée pour event kinds déjà validés. |
## Recovery allowlistée
La recovery `allowlisted_inner_spl_transfer` n'est pas une règle globale. Elle s'applique seulement aux event kinds explicitement autorisés dans le code. Cette restriction protège les futurs décodeurs : une nouvelle surface ne doit jamais créer des legs fee à partir de transferts internes tant que la sémantique n'a pas été inspectée.
Résultats de validation croisée en `0.7.56` :
| Base / surface | Effet observé |
|---|---|
| `meteora_dbc` | Aucun usage de l'allowlist générique ; chemins spécialisés DBC conservés. |
| `raydium_launchpad` | `212` parents enrichis en legs : `claim_creator_fee`, `claim_platform_fee`, `claim_platform_fee_from_vault`, `collect_fee`. |
| `raydium_cpmm` | `collect_creator_fee` enrichi ; `collect_fund_fee` / `collect_protocol_fee` explicités sans transfert exploitable. |
| `pump_swap` | `collect_coin_creator_fee` et un `transfer_creator_fees_to_pump_v2` enrichis ; autres cas zero/no-transfer explicités. |
| `pump_fees` | `crank_donation_fee_pda` et `sweep_buyback` enrichis ; events déjà scalaires conservés. |
## Contrôles SQL obligatoires
### Parent scalaire sans leg
```sql
SELECT
de.protocol_name,
de.event_kind,
tx.signature,
fee.id AS fee_event_id,
fee.fee_token_mint,
fee.fee_amount_raw,
fee.payload_json
FROM k_sol_fee_events fee
JOIN k_sol_dex_decoded_events de
ON de.id = fee.decoded_event_id
JOIN k_sol_chain_transactions tx
ON tx.id = fee.transaction_id
LEFT JOIN k_sol_fee_event_amounts fea
ON fea.fee_event_id = fee.id
WHERE COALESCE(TRIM(fee.fee_token_mint), '') <> ''
AND COALESCE(TRIM(fee.fee_amount_raw), '') <> ''
AND fea.id IS NULL
ORDER BY
de.protocol_name,
de.event_kind,
tx.signature
LIMIT 100;
```
Attendu : vide.
### Legs orphelins
```sql
SELECT
fea.id,
fea.fee_event_id,
fea.transaction_id,
fea.decoded_event_id
FROM k_sol_fee_event_amounts fea
LEFT JOIN k_sol_fee_events fee
ON fee.id = fea.fee_event_id
WHERE fee.id IS NULL;
```
Attendu : vide.
### Résumé parent/legs par event
```sql
SELECT
de.protocol_name,
de.event_kind,
COUNT(DISTINCT fee.id) AS fee_parent_count,
COUNT(DISTINCT CASE
WHEN COALESCE(TRIM(fee.fee_token_mint), '') <> ''
AND COALESCE(TRIM(fee.fee_amount_raw), '') <> ''
THEN fee.id
ELSE NULL
END) AS parent_with_scalar_amount_count,
COUNT(DISTINCT fea.id) AS fee_amount_leg_count,
MIN(tx.signature) AS sample_signature
FROM k_sol_fee_events fee
JOIN k_sol_dex_decoded_events de
ON de.id = fee.decoded_event_id
JOIN k_sol_chain_transactions tx
ON tx.id = fee.transaction_id
LEFT JOIN k_sol_fee_event_amounts fea
ON fea.fee_event_id = fee.id
GROUP BY
de.protocol_name,
de.event_kind
ORDER BY
de.protocol_name,
de.event_kind;
```
## Règles pour `0.7.57 meteora_dlmm`
- Les instructions `claim_fee`, `claim_fee2`, `withdraw_protocol_fee`, `zap_protocol_fee`, `CompositionFee`, `ClaimFee`, `ClaimFee2` doivent utiliser `k_sol_fee_event_amounts` dès qu'un montant/mint fiable est disponible.
- Les rewards (`claim_reward*`, `fund_reward`, `withdraw_ineligible_reward`) vont vers `k_sol_reward_events`, pas vers fees, sauf sémantique contraire prouvée.
- Les `composition_fee` de swap/liquidity ne doivent pas être double-comptés si déjà inclus dans le trade/liquidity effectif.
- Toute recovery générique doit être déclarée par policy explicite et tests synthétiques ; ne pas ajouter DLMM à l'allowlist sans audit par event kind.

View File

@@ -0,0 +1,161 @@
<!-- file: docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md -->
# Meteora DBC Event Coverage Report — `0.7.56 final`
## Statut final
La tranche `0.7.56 meteora_dbc` est clôturée.
Program id :
```text
dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN
```
Source locale prioritaire :
```text
idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json
```
Surface IDL : `28` instructions, `23` events Anchor, `9` accounts, `59` types.
## Résultat build/replay final
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
0 tokenAccount
1056 candle upserts
instructionObservations = 7167
resetDeleted = 3583
catalog = 86 tokens / 60 pools / 60 pairs
```
Replay final recommandé pour reproduire :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
## Décisions métier verrouillées
### Swaps
- `meteora_dbc.swap` et `meteora_dbc.swap2` sont les seules entrées candidates trade/candle directes.
- Les trades/candles ne sont produits que si les montants exécutés et les mints base/quote sont fiables.
- Les montants de `swap2` doivent être dérivés du layout et/ou des CPI SPL effectifs ; ne pas utiliser naïvement les bornes d'instruction.
- Les events Anchor `EvtSwap` / `EvtSwap2` restent decoded-only s'ils ne portent pas un contexte mint/pair suffisant ou s'ils doublonnent l'instruction matérialisée.
### Lifecycle / migration / lockers
- `initialize_virtual_pool_with_spl_token` et `initialize_virtual_pool_with_token2022` alimentent lifecycle/catalog lorsque les comptes pool/base/quote/config sont fiables.
- `create_locker`, `migrate_meteora_damm_claim_lp_token`, `migrate_meteora_damm_lock_lp_token`, `migration_damm_v2*` et `migrate_meteora_damm*` sont lifecycle, pas liquidity artificielle.
- Les metadata-only restent decoded-only avec raison explicite si elles n'apportent pas de cible métier fiable.
### Admin/config
- `create_config`, `create_operator_account`, `close_*operator*`, metadata, `transfer_pool_creator` et events config/admin alimentent `k_sol_pool_admin_events` uniquement si l'acteur et la cible sont fiables.
- Les payloads génériques ou incomplets restent audit/decoded-only.
### Fees
- Les fees DBC utilisent le modèle parent+legs : `k_sol_fee_events` + `k_sol_fee_event_amounts`.
- Les maxima d'instruction (`maxAmount*`, `u64::MAX`, bornes de claim) ne sont pas des montants exécutés.
- Les montants fiables proviennent des CPI SPL, des legs explicitement reconstruits ou des lamport balance deltas prouvés.
- Les events Anchor fee sans mint restent decoded-only avec `skipFeeReason`.
- Les cas sans transfert réel portent `fee_instruction_has_no_actual_transfer` ou `fee_instruction_has_only_zero_amount_transfers`.
## Matérialisation fee finale
| Event kind | Fee parents | Parents scalaires | Amount legs | Décision |
|---|---:|---:|---:|---|
| `meteora_dbc.claim_creator_trading_fee` | 8 | 8 | 8 | Mono-leg fiable. |
| `meteora_dbc.claim_partner_pool_creation_fee` | 10 | 10 | 10 | Mono-leg fiable. |
| `meteora_dbc.claim_protocol_fee` | 10 | 10 | 10 | Mono-leg fiable. |
| `meteora_dbc.claim_protocol_pool_creation_fee` | 10 | 10 | 10 | Mono-leg/lamport delta fiable. |
| `meteora_dbc.claim_trading_fee` | 11 | 6 | 18 | Mix mono-leg et multi-leg ; parent non agrégé pour multi-leg. |
| `meteora_dbc.creator_withdraw_surplus` | 2 | 2 | 2 | Mono-leg fiable ; résiduels sans transfert réel explicités. |
| `meteora_dbc.partner_withdraw_surplus` | 9 | 9 | 9 | Mono-leg fiable. |
| `meteora_dbc.withdraw_leftover` | 10 | 10 | 10 | Mono-leg fiable. |
| `meteora_dbc.withdraw_migration_fee` | 9 | 9 | 9 | Fee, pas migration target ; mono-leg fiable. |
| `meteora_dbc.zap_protocol_fee` | 10 | 10 | 10 | Mono-leg fiable. |
| **Total `meteora_dbc`** | **89** | n/a | **96** | Parent+legs validé. |
## Socle `k_sol_fee_event_amounts`
La version `0.7.56` ajoute un modèle durable pour les fees composés :
- `k_sol_fee_events` est le parent logique unique lié au `decoded_event_id` ;
- `k_sol_fee_event_amounts` contient les legs de montants, avec `leg_index`, `fee_component_kind`, `token_mint`, `amount_raw`, comptes source/destination et `amount_source` ;
- un parent avec `fee_token_mint + fee_amount_raw` crée automatiquement un leg scalaire ;
- un parent multi-leg/multi-mint laisse les champs scalaires du parent vides et stocke tout dans les legs ;
- les deletes/replays nettoient les legs avant ou avec le parent ;
- la requête de contrôle `parent scalar without leg` doit rester vide.
Sources `amount_source` connues en fin de tranche :
```text
parent_fee_event_amount
fee_event_amounts
inner_spl_transfer
lamport_balance_delta
allowlisted_inner_spl_transfer
```
## Recovery fee allowlistée
La recovery `allowlisted_inner_spl_transfer` est volontairement non globale.
Elle a été testée sur anciennes bases pour enrichir les surfaces déjà connues :
| Surface testée | Résultat |
|---|---|
| `raydium_launchpad` | `claim_creator_fee`, `claim_platform_fee`, `claim_platform_fee_from_vault`, `collect_fee` enrichis en legs depuis CPI SPL. |
| `raydium_cpmm` | `collect_creator_fee` enrichi ; `collect_fund_fee` et `collect_protocol_fee` restent sans transfert réel exploitable dans le corpus testé. |
| `pump_swap` | `collect_coin_creator_fee` et certains `transfer_creator_fees_to_pump_v2` enrichis ; cas zero/no-transfer explicités. |
| `pump_fees` | `crank_donation_fee_pda` et `sweep_buyback` enrichis ; events déjà scalaires conservés. |
| `meteora_dbc` | Non concerné par l'allowlist générique ; DBC conserve ses chemins spécifiques. |
Règle pour les prochaines versions : tout nouveau decoder doit déclarer explicitement sa policy de récupération des montants fee. Aucun futur decoder ne doit hériter automatiquement de la recovery CPI SPL.
## Checks de fermeture
Les contrôles de fermeture exigés sont propres :
- fallback `upstream_git` `meteora_dbc` pour entrées couvertes localement : vide ;
- decoded `meteora_dbc` sans coverage : vide ;
- successful non-materialized sans `skip*Reason` ou policy explicite : vide ;
- failed tx avec materialization métier : vide ;
- multi-target materialization : vide ;
- non-swap DBC vers trade/candle : vide ;
- parent fee scalaire sans leg : vide ;
- legs fee orphelins : vide ;
- watchlist globale sans backlog dominant `meteora_dbc`.
## Fichiers de référence
```text
kb_lib/src/dex/meteora_dbc.rs
kb_lib/src/non_trade_event_materialization.rs
kb_lib/src/db/queries/fee_event_amount.rs
kb_lib/src/db/entities/fee_event_amount.rs
kb_lib/src/db/dtos/fee_event_amount.rs
validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql
docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md
docs/VALIDATION_STATUS_0_7_56_FINAL.md
docs/prompts/PROMPT_0_7_57_METEORA_DLMM_FULL_DECODE_MATERIALIZATION.md
```
## Décision
`0.7.56 meteora_dbc` est clôturé. La prochaine tranche est `0.7.57 meteora_dlmm` en full decode + full materialization.