<!-- 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.
