0.7.56
This commit is contained in:
@@ -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`.
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -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. |
|
||||
|
||||
|
||||
51
docs/VALIDATION_STATUS_0_7_56_FINAL.md
Normal file
51
docs/VALIDATION_STATUS_0_7_56_FINAL.md
Normal 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
151
docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md
Normal file
151
docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md
Normal 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.
|
||||
161
docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md
Normal file
161
docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md
Normal 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.
|
||||
Reference in New Issue
Block a user