0.7.39
This commit is contained in:
@@ -69,4 +69,4 @@
|
||||
0.7.36 - Consolidation de la famille Meteora : corpus mixte `meteora_damm_v1`, `meteora_damm_v2`, `meteora_dbc` et `meteora_dlmm`, correction des discriminants DAMM v2 / DBC, validation du profil `0.7.36_meteora_family_consolidation`, et reclassement explicite des swaps DAMM v2 / DBC sans payload montant/prix en `non_actionable_trade` afin d’éviter tout trade/candle artificiel.
|
||||
0.7.37 - Première tranche metadata/catalog : ajout du profil `0.7.37_token_metadata_catalog_enrichment`, exposition des compteurs metadata dans diagnostics/validation et raccordement UI Demo Pipeline 2 sans rendre les metadata manquantes bloquantes.
|
||||
0.7.38 - Priorisation des metadata manquantes : ajout du profil `0.7.38_token_metadata_gap_prioritization`, samples `tokenMetadataGapSamples`, priorités tradable/quote/catalog, raccordement UI Demo Pipeline 2 et maintien du caractère non bloquant des metadata incomplètes.
|
||||
0.7.39 - Tranche sûre launch surfaces : ensemencement contrôlé des origins LaunchLab/Launchpad/LetsBonk/Bonk.fun/Bags/Moonshot/Moonit/Boop.fun/Believe, Heaven préparé mais désactivé, mappings génériques vérifiés, samples diagnostics `launchOriginSamples` / `poolOriginSamples`, profil `0.7.39_launch_surface_origin_baseline`, raccordement Demo Pipeline 2 et maintien de l’invariant sans faux trade/candle ni program id fictif.
|
||||
0.7.39 - Réorientation DEX-first : ajout du rôle stratégique `surfaceRole` dans la matrice DEX (`dex_effective`, `aggregator_router`, `launch_surface`, `to_verify`), profil `0.7.39_dex_first_effective_swap_surfaces`, ajout de `metaDAO` et `Printr` comme entrées `to_verify` sans `program_id`, maintien des launch surfaces en état différé et des invariants sans faux trade/candle ni program id fictif.
|
||||
|
||||
@@ -114,7 +114,7 @@ La distinction de travail à partir de `0.7.39` est la suivante :
|
||||
|
||||
### 4.1. Matrice de travail
|
||||
|
||||
Depuis `0.7.29`, la matrice de support DEX est portée par `kb_lib/src/dex_support_matrix.rs`. Elle centralise le code interne, la famille, la version, le type de surface, les program ids vérifiés localement, le statut de support, les capacités actuelles et les raisons de skip.
|
||||
Depuis `0.7.29`, la matrice de support DEX est portée par `kb_lib/src/dex_support_matrix.rs`. Elle centralise le code interne, la famille, la version, le type technique de surface, le rôle stratégique de surface (`dex_effective`, `aggregator_router`, `launch_surface`, `to_verify`), les program ids vérifiés localement, le statut de support, les capacités actuelles et les raisons de skip.
|
||||
|
||||
Depuis `0.7.30`, les événements décodés reçoivent aussi une classification plus fine : `eventLifecycleKind`, `eventActionability` et `nonTradeUseful`. Cette classification sert aux diagnostics et prépare la matérialisation future des événements non-trade sans alimenter directement les trades/candles.
|
||||
|
||||
|
||||
@@ -787,7 +787,7 @@ Contraintes :
|
||||
Réalisé :
|
||||
|
||||
- ajouter `kb_lib/src/dex_support_matrix.rs` comme source commune de metadata DEX/surfaces ;
|
||||
- exposer pour chaque entrée : code interne, famille, version, type de surface, program id connu ou à vérifier, support actuel, statut, confiance, raisons de skip et activation catalogue ;
|
||||
- exposer pour chaque entrée : code interne, famille, version, type technique de surface, rôle stratégique de surface, program id connu ou à vérifier, support actuel, statut, confiance, raisons de skip et activation catalogue ;
|
||||
- raccorder `dex_catalog`, `transaction_classification` et `protocol_candidate_recording` à cette matrice ;
|
||||
- ajouter le profil `0.7.29_multi_dex_matrix_baseline` ;
|
||||
- exposer la matrice dans le rapport de validation local ;
|
||||
@@ -947,9 +947,9 @@ Décision : `0.7.38` est clos. La clôture `0.7.38-B` conserve la logique de sta
|
||||
### 6.071. Version `0.7.39` — Réorientation DEX-first et inventaire des DEX effectifs
|
||||
Objectif : remplacer la priorité précédemment donnée aux launch surfaces par une consolidation des vrais DEX sur lesquels les swaps et événements de marché sont exécutés.
|
||||
|
||||
À faire :
|
||||
Réalisé :
|
||||
|
||||
- modifier la matrice DEX pour distinguer explicitement : `dex_effective`, `aggregator/router`, `launch_surface`, `to_verify` ;
|
||||
- modifier la matrice DEX pour distinguer explicitement les rôles `dex_effective`, `aggregator_router`, `launch_surface`, `to_verify` ;
|
||||
- vérifier les DEX de swap principaux déjà connus : `pump_swap`, `raydium_cpmm`, `raydium_clmm`, `raydium_amm_v4`, `raydium_stable_swap`, `meteora_dlmm`, `meteora_damm_v1`, `meteora_damm_v2`, `meteora_dbc`, `orca_whirlpools`, `fluxbeam`, `dexlab` ;
|
||||
- ajouter `metaDAO` et `Printr` comme entrées `to_verify` dans la matrice, sans `program_id` tant qu’ils ne sont pas prouvés ;
|
||||
- rechercher ou confirmer les `program_id` inconnus depuis les corpus locaux, les protocol candidates, DEX Screener, les explorateurs et les transactions résolues ;
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
<div class="mb-3">
|
||||
<label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label>
|
||||
<select id="demoPipeline2ValidationProfileSelect" class="form-select">
|
||||
<option value="0.7.39_launch_surface_origin_baseline" selected>0.7.39 — launch surface origin baseline</option>
|
||||
<option value="0.7.39_dex_first_effective_swap_surfaces" selected>0.7.39 — DEX-first effective swap surfaces</option>
|
||||
<option value="0.7.38_token_metadata_gap_prioritization">0.7.38 — token metadata gap prioritization</option>
|
||||
<option value="0.7.37_token_metadata_catalog_enrichment">0.7.37 — token metadata/catalog enrichment</option>
|
||||
<option value="0.7.36_meteora_family_consolidation">0.7.36 — Meteora family consolidation</option>
|
||||
|
||||
@@ -21,9 +21,13 @@ family: string,
|
||||
*/
|
||||
version: string,
|
||||
/**
|
||||
* Surface type: launch, bonding curve, AMM, CLMM, DLMM, router, aggregator or unknown.
|
||||
* Technical surface type: launch, bonding curve, AMM, CLMM, DLMM, router, aggregator or unknown.
|
||||
*/
|
||||
surfaceType: string,
|
||||
/**
|
||||
* Strategic surface role: dex_effective, aggregator_router, launch_surface or to_verify.
|
||||
*/
|
||||
surfaceRole: string,
|
||||
/**
|
||||
* Primary Solana program id, when verified in local constants or docs.
|
||||
*/
|
||||
|
||||
@@ -225,8 +225,10 @@ pub(crate) struct DemoPipeline2DexSupportMatrixEntry {
|
||||
pub family: std::string::String,
|
||||
/// Protocol version or `unknown` when not verified locally.
|
||||
pub version: std::string::String,
|
||||
/// Surface type: launch, bonding curve, AMM, CLMM, DLMM, router, aggregator or unknown.
|
||||
/// Technical surface type: launch, bonding curve, AMM, CLMM, DLMM, router, aggregator or unknown.
|
||||
pub surface_type: std::string::String,
|
||||
/// Strategic surface role: dex_effective, aggregator_router, launch_surface or to_verify.
|
||||
pub surface_role: std::string::String,
|
||||
/// Primary Solana program id, when verified in local constants or docs.
|
||||
pub program_id: std::option::Option<std::string::String>,
|
||||
/// Optional router program id, when this entry uses a distinct router.
|
||||
@@ -1263,7 +1265,7 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
|
||||
let service = kb_lib::LocalPipelineValidationService::new(database.clone());
|
||||
let profile_code = match request {
|
||||
Some(request) => request.profile_code,
|
||||
None => "0.7.39_launch_surface_origin_baseline".to_string(),
|
||||
None => "0.7.39_dex_first_effective_swap_surfaces".to_string(),
|
||||
};
|
||||
let run_result = match profile_code.as_str() {
|
||||
"0.7.27" | "0.7.27_dexes_non_regression" => {
|
||||
@@ -1302,7 +1304,7 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
|
||||
"0.7.38" | "0.7.38_token_metadata_gap_prioritization" => {
|
||||
service.validate_v0_7_38_current_database().await
|
||||
},
|
||||
"0.7.39" | "0.7.39_launch_surface_origin_baseline" => {
|
||||
"0.7.39" | "0.7.39_dex_first_effective_swap_surfaces" | "0.7.39_launch_surface_origin_baseline" => {
|
||||
service.validate_v0_7_39_current_database().await
|
||||
},
|
||||
other => Err(kb_lib::Error::InvalidState(format!(
|
||||
@@ -1762,6 +1764,7 @@ fn demo_pipeline2_map_dex_support_matrix_entry(
|
||||
family: entry.family,
|
||||
version: entry.version,
|
||||
surface_type: entry.surface_type,
|
||||
surface_role: entry.surface_role,
|
||||
program_id: entry.program_id,
|
||||
router_program_id: entry.router_program_id,
|
||||
program_id_status: entry.program_id_status,
|
||||
|
||||
@@ -186,16 +186,16 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
assert!(dex_id > 0);
|
||||
let dex = crate::query_dexs_get_by_code(&database, "raydium")
|
||||
let dex = crate::query_dexs_get_by_code(&database, "raydium_amm_v4")
|
||||
.await
|
||||
.expect("get dex must succeed");
|
||||
assert!(dex.is_some());
|
||||
assert_eq!(dex.expect("dex must exist").name, "Raydium");
|
||||
assert_eq!(dex.expect("dex must exist").name, "Raydium AMM v4");
|
||||
let dexes = crate::query_dexs_list(&database).await.expect("list dexes must succeed");
|
||||
assert_eq!(dexes.len(), 1);
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -181,7 +181,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -202,7 +202,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -140,7 +140,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -167,7 +167,7 @@ mod tests {
|
||||
.expect("database init must succeed");
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
&database,
|
||||
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
|
||||
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
|
||||
)
|
||||
.await
|
||||
.expect("dex upsert must succeed");
|
||||
|
||||
@@ -353,8 +353,8 @@ mod tests {
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
service.database().as_ref(),
|
||||
&crate::DexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
"raydium_amm_v4".to_string(),
|
||||
"Raydium AMM v4".to_string(),
|
||||
Some("DexProgram111111111111111111111111111111111".to_string()),
|
||||
None,
|
||||
true,
|
||||
|
||||
@@ -1009,8 +1009,8 @@ mod tests {
|
||||
let dex_id = crate::query_dexs_upsert(
|
||||
persistence.database().as_ref(),
|
||||
&crate::DexDto::new(
|
||||
"raydium".to_string(),
|
||||
"Raydium".to_string(),
|
||||
"raydium_amm_v4".to_string(),
|
||||
"Raydium AMM v4".to_string(),
|
||||
Some("DexProgram111111111111111111111111111111111".to_string()),
|
||||
None,
|
||||
true,
|
||||
|
||||
@@ -92,7 +92,7 @@ mod tests {
|
||||
#[test]
|
||||
fn known_active_dexes_are_available_from_catalog() {
|
||||
let codes = [
|
||||
"raydium",
|
||||
"raydium_amm_v4",
|
||||
"raydium_cpmm",
|
||||
"raydium_clmm",
|
||||
"pump_fun",
|
||||
|
||||
@@ -149,7 +149,7 @@ impl DexDetectService {
|
||||
decoded_event: &crate::DexDecodedEventDto,
|
||||
) -> Result<crate::DexPoolDetectionResult, crate::Error> {
|
||||
let dex_id_result =
|
||||
crate::dex_catalog::ensure_known_dex(self.database.as_ref(), "raydium").await;
|
||||
crate::dex_catalog::ensure_known_dex(self.database.as_ref(), "raydium_amm_v4").await;
|
||||
let dex_id = match dex_id_result {
|
||||
Ok(dex_id) => dex_id,
|
||||
Err(error) => return Err(error),
|
||||
|
||||
@@ -19,8 +19,10 @@ pub struct DexSupportMatrixEntry {
|
||||
pub family: &'static str,
|
||||
/// Protocol version or `unknown` when not verified locally.
|
||||
pub version: &'static str,
|
||||
/// Surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
|
||||
/// Technical surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
|
||||
pub surface_type: &'static str,
|
||||
/// Strategic surface role used by the DEX-first roadmap: `dex_effective`, `aggregator_router`, `launch_surface` or `to_verify`.
|
||||
pub surface_role: &'static str,
|
||||
/// Primary Solana program id, when verified in local constants or docs.
|
||||
pub program_id: std::option::Option<&'static str>,
|
||||
/// Optional router program id, when this entry uses a distinct router.
|
||||
@@ -63,8 +65,10 @@ pub struct DexSupportMatrixEntryDto {
|
||||
pub family: std::string::String,
|
||||
/// Protocol version or `unknown` when not verified locally.
|
||||
pub version: std::string::String,
|
||||
/// Surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
|
||||
/// Technical surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
|
||||
pub surface_type: std::string::String,
|
||||
/// Strategic surface role used by the DEX-first roadmap: `dex_effective`, `aggregator_router`, `launch_surface` or `to_verify`.
|
||||
pub surface_role: std::string::String,
|
||||
/// Primary Solana program id, when verified in local constants or docs.
|
||||
pub program_id: std::option::Option<std::string::String>,
|
||||
/// Optional router program id, when this entry uses a distinct router.
|
||||
@@ -104,6 +108,7 @@ impl DexSupportMatrixEntryDto {
|
||||
family: entry.family.to_string(),
|
||||
version: entry.version.to_string(),
|
||||
surface_type: entry.surface_type.to_string(),
|
||||
surface_role: entry.surface_role.to_string(),
|
||||
program_id: match entry.program_id {
|
||||
Some(program_id) => Some(program_id.to_string()),
|
||||
None => None,
|
||||
@@ -138,6 +143,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "pump",
|
||||
version: "bonding_curve",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: Some(crate::PUMP_FUN_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -159,6 +165,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "pump",
|
||||
version: "amm",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::PUMP_SWAP_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -180,6 +187,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "raydium",
|
||||
version: "cpmm",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::RAYDIUM_CPMM_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -201,6 +209,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "raydium",
|
||||
version: "clmm",
|
||||
surface_type: "CLMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::RAYDIUM_CLMM_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -222,6 +231,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "raydium",
|
||||
version: "amm_v4",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -237,33 +247,13 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
skip_reason: Some("not_observed_in_0_7_28_replay"),
|
||||
catalog_enabled: true,
|
||||
},
|
||||
DexSupportMatrixEntry {
|
||||
code: "raydium",
|
||||
display_name: "Raydium AMM v4",
|
||||
family: "raydium",
|
||||
version: "amm_v4_alias",
|
||||
surface_type: "AMM",
|
||||
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
observed: false,
|
||||
decoded: true,
|
||||
materialized: true,
|
||||
trade_candidate: true,
|
||||
candle_candidate: true,
|
||||
pair_candidate: true,
|
||||
pool_candidate: true,
|
||||
status: "partial",
|
||||
confidence: "medium",
|
||||
skip_reason: Some("legacy_catalog_alias_for_raydium_amm_v4"),
|
||||
catalog_enabled: true,
|
||||
},
|
||||
DexSupportMatrixEntry {
|
||||
code: "raydium_launchlab",
|
||||
display_name: "Raydium LaunchLab",
|
||||
family: "raydium",
|
||||
version: "launchlab",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -285,6 +275,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "raydium",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "to_verify",
|
||||
@@ -306,6 +297,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "raydium",
|
||||
version: "router",
|
||||
surface_type: "router",
|
||||
surface_role: "aggregator_router",
|
||||
program_id: Some(crate::RAYDIUM_AMM_ROUTING_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -327,6 +319,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "raydium",
|
||||
version: "stable_swap",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -348,6 +341,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "meteora",
|
||||
version: "dlmm",
|
||||
surface_type: "DLMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::METEORA_DLMM_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -369,6 +363,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "meteora",
|
||||
version: "unknown",
|
||||
surface_type: "unknown",
|
||||
surface_role: "to_verify",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "to_verify",
|
||||
@@ -390,6 +385,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "meteora",
|
||||
version: "damm_v1",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::METEORA_DAMM_V1_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -411,6 +407,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "meteora",
|
||||
version: "damm_v2",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::METEORA_DAMM_V2_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -432,6 +429,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "meteora",
|
||||
version: "dbc",
|
||||
surface_type: "bonding_curve",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::METEORA_DBC_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -453,6 +451,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "orca",
|
||||
version: "whirlpools",
|
||||
surface_type: "CLMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -474,6 +473,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "fluxbeam",
|
||||
version: "unknown",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::FLUXBEAM_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -495,6 +495,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "dexlab",
|
||||
version: "unknown",
|
||||
surface_type: "AMM",
|
||||
surface_role: "dex_effective",
|
||||
program_id: Some(crate::DEXLAB_PROGRAM_ID),
|
||||
router_program_id: None,
|
||||
program_id_status: "known",
|
||||
@@ -516,6 +517,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "bags",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -537,6 +539,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "bonk",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -558,6 +561,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "bonk",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -579,6 +583,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "bonk",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -600,6 +605,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "okx",
|
||||
version: "unknown",
|
||||
surface_type: "aggregator",
|
||||
surface_role: "aggregator_router",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -621,6 +627,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "boop",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -642,6 +649,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "moonshot",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -663,6 +671,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "believe",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -678,12 +687,57 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
skip_reason: Some("program_id_to_verify"),
|
||||
catalog_enabled: false,
|
||||
},
|
||||
DexSupportMatrixEntry {
|
||||
code: "metadao",
|
||||
display_name: "metaDAO",
|
||||
family: "metadao",
|
||||
version: "unknown",
|
||||
surface_type: "unknown",
|
||||
surface_role: "to_verify",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "to_verify",
|
||||
observed: false,
|
||||
decoded: false,
|
||||
materialized: false,
|
||||
trade_candidate: false,
|
||||
candle_candidate: false,
|
||||
pair_candidate: false,
|
||||
pool_candidate: false,
|
||||
status: "to_verify",
|
||||
confidence: "low",
|
||||
skip_reason: Some("surface_and_program_id_to_verify"),
|
||||
catalog_enabled: false,
|
||||
},
|
||||
DexSupportMatrixEntry {
|
||||
code: "printr",
|
||||
display_name: "Printr",
|
||||
family: "printr",
|
||||
version: "unknown",
|
||||
surface_type: "unknown",
|
||||
surface_role: "to_verify",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "to_verify",
|
||||
observed: false,
|
||||
decoded: false,
|
||||
materialized: false,
|
||||
trade_candidate: false,
|
||||
candle_candidate: false,
|
||||
pair_candidate: false,
|
||||
pool_candidate: false,
|
||||
status: "to_verify",
|
||||
confidence: "low",
|
||||
skip_reason: Some("surface_and_program_id_to_verify"),
|
||||
catalog_enabled: false,
|
||||
},
|
||||
DexSupportMatrixEntry {
|
||||
code: "zora",
|
||||
display_name: "Zora",
|
||||
family: "zora",
|
||||
version: "unknown",
|
||||
surface_type: "unknown",
|
||||
surface_role: "to_verify",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "to_verify",
|
||||
@@ -705,6 +759,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "moonit",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -726,6 +781,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "launchbeam",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -747,6 +803,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
|
||||
family: "heaven",
|
||||
version: "unknown",
|
||||
surface_type: "launch",
|
||||
surface_role: "launch_surface",
|
||||
program_id: None,
|
||||
router_program_id: None,
|
||||
program_id_status: "unknown",
|
||||
@@ -812,7 +869,7 @@ pub fn dex_support_matrix_entry_by_program_id(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn matrix_contains_required_0_7_29_entries() {
|
||||
fn matrix_contains_required_0_7_39_dex_first_entries() {
|
||||
let codes = [
|
||||
"pump_fun",
|
||||
"pump_swap",
|
||||
@@ -837,6 +894,8 @@ mod tests {
|
||||
"launchbeam",
|
||||
"heaven",
|
||||
"dexlab",
|
||||
"metadao",
|
||||
"printr",
|
||||
];
|
||||
for code in codes {
|
||||
let entry = crate::dex_support_matrix_entry_by_code(code);
|
||||
@@ -860,6 +919,8 @@ mod tests {
|
||||
"moonit",
|
||||
"launchbeam",
|
||||
"heaven",
|
||||
"metadao",
|
||||
"printr",
|
||||
];
|
||||
for code in codes {
|
||||
let entry = match crate::dex_support_matrix_entry_by_code(code) {
|
||||
@@ -932,7 +993,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matrix_keeps_0_7_39_launch_surfaces_non_trade_materialized() {
|
||||
fn matrix_keeps_0_7_39_deferred_surfaces_non_trade_materialized() {
|
||||
let codes = [
|
||||
"raydium_launchlab",
|
||||
"raydium_launchpad",
|
||||
@@ -958,6 +1019,50 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matrix_marks_effective_dexes_for_dex_first_work() {
|
||||
let codes = [
|
||||
"pump_swap",
|
||||
"raydium_cpmm",
|
||||
"raydium_clmm",
|
||||
"raydium_amm_v4",
|
||||
"raydium_stable_swap",
|
||||
"meteora_dlmm",
|
||||
"meteora_damm_v1",
|
||||
"meteora_damm_v2",
|
||||
"meteora_dbc",
|
||||
"orca_whirlpools",
|
||||
"fluxbeam",
|
||||
"dexlab",
|
||||
];
|
||||
for code in codes {
|
||||
let entry = match crate::dex_support_matrix_entry_by_code(code) {
|
||||
Some(entry) => entry,
|
||||
None => panic!("missing matrix entry for {}", code),
|
||||
};
|
||||
assert_eq!(entry.surface_role, "dex_effective", "{} must be DEX-first", code);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matrix_keeps_metadao_and_printr_unverified_without_program_id() {
|
||||
let codes = ["metadao", "printr"];
|
||||
for code in codes {
|
||||
let entry = match crate::dex_support_matrix_entry_by_code(code) {
|
||||
Some(entry) => entry,
|
||||
None => panic!("missing matrix entry for {}", code),
|
||||
};
|
||||
assert_eq!(entry.surface_role, "to_verify");
|
||||
assert_eq!(entry.program_id_status, "to_verify");
|
||||
assert!(entry.program_id.is_none());
|
||||
assert!(!entry.decoded);
|
||||
assert!(!entry.materialized);
|
||||
assert!(!entry.trade_candidate);
|
||||
assert!(!entry.candle_candidate);
|
||||
assert!(!entry.catalog_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matrix_dto_preserves_core_fields() {
|
||||
let entry = match crate::dex_support_matrix_entry_by_code("pump_swap") {
|
||||
@@ -967,6 +1072,7 @@ mod tests {
|
||||
let dto = crate::DexSupportMatrixEntryDto::from_entry(entry);
|
||||
assert_eq!(dto.code, "pump_swap");
|
||||
assert_eq!(dto.program_id, Some(crate::PUMP_SWAP_PROGRAM_ID.to_string()));
|
||||
assert_eq!(dto.surface_role, "dex_effective");
|
||||
assert!(dto.trade_candidate);
|
||||
assert!(dto.candle_candidate);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ impl LaunchOriginService {
|
||||
return Self { database, persistence };
|
||||
}
|
||||
|
||||
/// Ensures that every built-in launch surface tracked by `0.7.39` exists.
|
||||
/// Ensures that every deferred built-in launch surface exists.
|
||||
pub async fn ensure_target_launch_surfaces(&self) -> Result<std::vec::Vec<i64>, crate::Error> {
|
||||
let mut surface_ids = std::vec::Vec::new();
|
||||
for spec in BUILTIN_LAUNCH_SURFACE_SPECS {
|
||||
|
||||
@@ -278,18 +278,26 @@ impl LocalPipelineValidationConfig {
|
||||
return config;
|
||||
}
|
||||
|
||||
/// Builds the `0.7.39` launch surface origin baseline validation config.
|
||||
/// Builds the `0.7.39` DEX-first effective swap surfaces validation config.
|
||||
///
|
||||
/// This profile keeps the `0.7.38` metadata-gap semantics and requires the
|
||||
/// static DEX matrix invariants that prevent planned launch surfaces from
|
||||
/// being treated as priced trade/candle producers before corpus-backed
|
||||
/// decoders are available.
|
||||
pub fn v0_7_39_launch_surface_origin_baseline() -> Self {
|
||||
/// static DEX matrix invariants that distinguish effective swap surfaces,
|
||||
/// routers/aggregators, deferred launch surfaces and unverified candidates.
|
||||
pub fn v0_7_39_dex_first_effective_swap_surfaces() -> Self {
|
||||
let mut config = Self::v0_7_38_token_metadata_gap_prioritization();
|
||||
config.profile_code = "0.7.39_launch_surface_origin_baseline".to_string();
|
||||
config.profile_code = "0.7.39_dex_first_effective_swap_surfaces".to_string();
|
||||
config.require_dex_support_matrix_semantics = true;
|
||||
return config;
|
||||
}
|
||||
|
||||
/// Builds the legacy `0.7.39` launch-surface validation alias.
|
||||
///
|
||||
/// The implementation now delegates to the DEX-first profile so callers that
|
||||
/// still pass the previous profile code do not accidentally revive the old
|
||||
/// launch-surface priority.
|
||||
pub fn v0_7_39_launch_surface_origin_baseline() -> Self {
|
||||
return Self::v0_7_39_dex_first_effective_swap_surfaces();
|
||||
}
|
||||
}
|
||||
|
||||
/// A single local pipeline validation issue.
|
||||
@@ -519,11 +527,11 @@ impl LocalPipelineValidationService {
|
||||
return self.validate_current_database(&config).await;
|
||||
}
|
||||
|
||||
/// Diagnoses the current database with the `0.7.39` launch-origin baseline profile.
|
||||
/// Diagnoses the current database with the `0.7.39` DEX-first profile.
|
||||
pub async fn validate_v0_7_39_current_database(
|
||||
&self,
|
||||
) -> Result<crate::LocalPipelineValidationRunDto, crate::Error> {
|
||||
let config = crate::LocalPipelineValidationConfig::v0_7_39_launch_surface_origin_baseline();
|
||||
let config = crate::LocalPipelineValidationConfig::v0_7_39_dex_first_effective_swap_surfaces();
|
||||
return self.validate_current_database(&config).await;
|
||||
}
|
||||
}
|
||||
@@ -649,6 +657,7 @@ pub fn validate_local_pipeline_diagnostics_summary(
|
||||
|| config.profile_code == "0.7.36_meteora_family_consolidation"
|
||||
|| config.profile_code == "0.7.37_token_metadata_catalog_enrichment"
|
||||
|| config.profile_code == "0.7.38_token_metadata_gap_prioritization"
|
||||
|| config.profile_code == "0.7.39_dex_first_effective_swap_surfaces"
|
||||
|| config.profile_code == "0.7.39_launch_surface_origin_baseline";
|
||||
if config.require_all_expected_dexes || missing_expected_dex_is_warning {
|
||||
for expected_dex_code in &expected_dex_codes {
|
||||
@@ -898,16 +907,48 @@ fn validate_dex_support_matrix_semantics(
|
||||
});
|
||||
}
|
||||
if (entry.status == "planned" || entry.status == "to_verify" || entry.status == "unknown")
|
||||
&& entry.surface_type == "launch"
|
||||
&& (entry.surface_role == "launch_surface" || entry.surface_role == "to_verify")
|
||||
&& (entry.decoded
|
||||
|| entry.materialized
|
||||
|| entry.trade_candidate
|
||||
|| entry.candle_candidate)
|
||||
{
|
||||
issues.push(crate::LocalPipelineValidationIssueDto {
|
||||
code: "inactive_launch_surface_matrix_entry_actionable".to_string(),
|
||||
code: "inactive_deferred_surface_matrix_entry_actionable".to_string(),
|
||||
message: format!(
|
||||
"inactive launch surface '{}' must not be decoded, materialized, or priced as trade/candle candidate",
|
||||
"inactive deferred surface '{}' must not be decoded, materialized, or priced as trade/candle candidate",
|
||||
entry_code
|
||||
),
|
||||
subject: Some(entry_code.clone()),
|
||||
blocking: true,
|
||||
});
|
||||
}
|
||||
if entry.surface_role == "aggregator_router"
|
||||
&& (entry.trade_candidate || entry.candle_candidate || entry.catalog_enabled)
|
||||
{
|
||||
issues.push(crate::LocalPipelineValidationIssueDto {
|
||||
code: "aggregator_router_matrix_entry_direct_trade_enabled".to_string(),
|
||||
message: format!(
|
||||
"aggregator/router '{}' must not be enabled as a direct trade/candle surface before proof",
|
||||
entry_code
|
||||
),
|
||||
subject: Some(entry_code.clone()),
|
||||
blocking: true,
|
||||
});
|
||||
}
|
||||
if entry.surface_role == "to_verify"
|
||||
&& (entry.program_id.is_some()
|
||||
|| entry.program_id_status != "to_verify"
|
||||
|| entry.catalog_enabled
|
||||
|| entry.decoded
|
||||
|| entry.materialized
|
||||
|| entry.trade_candidate
|
||||
|| entry.candle_candidate)
|
||||
{
|
||||
issues.push(crate::LocalPipelineValidationIssueDto {
|
||||
code: "to_verify_matrix_entry_promoted_without_proof".to_string(),
|
||||
message: format!(
|
||||
"to-verify surface '{}' must not expose program id, catalog activation, decoding or trade/candle materialization without corpus proof",
|
||||
entry_code
|
||||
),
|
||||
subject: Some(entry_code.clone()),
|
||||
@@ -1397,12 +1438,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validation_accepts_0_7_39_launch_surface_origin_baseline() {
|
||||
fn validation_accepts_0_7_39_dex_first_effective_swap_surfaces() {
|
||||
let summary = make_0_7_28_summary_with_meteora();
|
||||
let config = crate::LocalPipelineValidationConfig::v0_7_39_launch_surface_origin_baseline();
|
||||
let config = crate::LocalPipelineValidationConfig::v0_7_39_dex_first_effective_swap_surfaces();
|
||||
let report = crate::validate_local_pipeline_diagnostics_summary(&summary, &config);
|
||||
assert!(report.validation_passed);
|
||||
assert_eq!(report.validation_profile_code, "0.7.39_launch_surface_origin_baseline");
|
||||
assert_eq!(report.validation_profile_code, "0.7.39_dex_first_effective_swap_surfaces");
|
||||
assert_eq!(report.blocking_issue_count, 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user