[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-15-simulation-mev-recherche-binaire-forks-etat":3},{"article":4,"author":61},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":39,"related_articles":40},"d6000000-0000-0000-0000-000000000115","a0000000-0000-0000-0000-000000000062","Deep EVM #15 : Simulation MEV — Recherche binaire, forks d'état et le délai de 12 secondes","deep-evm-15-simulation-mev-recherche-binaire-forks-etat","Construisez un pipeline de simulation MEV en Rust : fork de l'état blockchain avec revm, recherche binaire du montant optimal, simulation de bundles et respect du délai de 12 secondes par bloc.","## Pourquoi simuler ?\n\nDans le MEV, vous ne pouvez pas deviner — vous devez savoir exactement combien de profit une opportunité va générer, combien de gas elle consommera, et si la transaction réussira. La simulation est la seule façon d'obtenir ces réponses avant de soumettre un bundle.\n\n## Fork d'état avec revm\n\nrevm est une implémentation de l'EVM en Rust, optimisée pour la vitesse. Elle peut forker l'état d'un nœud Ethereum et exécuter des transactions localement :\n\n```rust\nuse revm::{EVM, db::CacheDB, primitives::*};\n\nfn simulate_swap(\n    state: &CacheDB,\n    swap_calldata: Bytes,\n    target_contract: Address,\n) -> Result\u003CSimResult, Error> {\n    let mut evm = EVM::new();\n    evm.database(state.clone());\n\n    evm.env.tx = TxEnv {\n        caller: bot_address(),\n        transact_to: TransactTo::Call(target_contract),\n        data: swap_calldata,\n        value: U256::ZERO,\n        gas_limit: 500_000,\n        ..Default::default()\n    };\n\n    let result = evm.transact()?;\n    Ok(SimResult {\n        gas_used: result.gas_used,\n        output: result.output,\n        success: result.is_success(),\n    })\n}\n```\n\n## Recherche binaire du montant optimal\n\nLa courbe profit\u002Fmontant pour un arbitrage AMM est concave — le profit augmente avec le montant jusqu'à un point optimal puis diminue. La recherche binaire est idéale :\n\n```rust\nfn find_optimal_amount(\n    state: &CacheDB,\n    cycle: &[Pool],\n    token: Address,\n) -> (U256, U256) {\n    let mut lo = U256::from(1_000_000); \u002F\u002F 0.001 ETH minimum\n    let mut hi = U256::from(100_000_000_000_000_000_000u128); \u002F\u002F 100 ETH max\n\n    for _ in 0..128 {\n        let mid = (lo + hi) \u002F 2;\n        let profit_at_mid = simulate_cycle(state, cycle, mid);\n        let profit_at_mid_plus = simulate_cycle(state, cycle, mid + lo);\n\n        if profit_at_mid_plus > profit_at_mid {\n            lo = mid;\n        } else {\n            hi = mid;\n        }\n    }\n\n    let optimal = (lo + hi) \u002F 2;\n    let profit = simulate_cycle(state, cycle, optimal);\n    (optimal, profit)\n}\n```\n\n## Le délai de 12 secondes\n\nLes blocs Ethereum arrivent toutes les 12 secondes. Votre pipeline doit :\n\n1. Recevoir le nouveau bloc\n2. Mettre à jour l'état local\n3. Détecter les nouvelles opportunités\n4. Simuler chaque opportunité\n5. Optimiser le montant\n6. Soumettre le bundle au constructeur de blocs\n\nTout cela en moins de ~6 secondes (pour laisser au constructeur le temps d'inclure votre bundle).\n\n```rust\nasync fn block_pipeline(block: Block) {\n    let start = Instant::now();\n    let deadline = start + Duration::from_secs(6);\n\n    \u002F\u002F Mise à jour de l'état\n    let state = update_state(&block).await;\n\n    \u002F\u002F Recherche d'opportunités en parallèle\n    let opportunities = find_opportunities(&state).await;\n\n    for opp in opportunities {\n        if Instant::now() > deadline {\n            break; \u002F\u002F Plus le temps — soumettre ce qu'on a\n        }\n\n        let (amount, profit) = find_optimal_amount(&state, &opp);\n        let gas_cost = estimate_gas_cost(&state, &opp, amount);\n\n        if profit > gas_cost * 2 { \u002F\u002F Marge de sécurité 2x\n            submit_bundle(&opp, amount).await;\n        }\n    }\n}\n```\n\n## Simulation de bundles\n\nUn bundle MEV peut contenir plusieurs transactions ordonnées. Simulez le bundle complet, pas les transactions individuelles :\n\n```rust\nfn simulate_bundle(\n    state: &CacheDB,\n    transactions: &[Transaction],\n) -> BundleResult {\n    let mut current_state = state.clone();\n    let mut total_profit = U256::ZERO;\n    let mut total_gas = 0u64;\n\n    for tx in transactions {\n        let result = simulate_on_state(&current_state, tx);\n        if !result.success {\n            return BundleResult::Failed;\n        }\n        current_state = result.new_state;\n        total_profit += result.profit;\n        total_gas += result.gas_used;\n    }\n\n    BundleResult::Success { total_profit, total_gas }\n}\n```\n\n## Conclusion\n\nLa simulation MEV est le pont entre la détection d'opportunités et la soumission de bundles rentables. revm pour le fork d'état, la recherche binaire pour l'optimisation, et le respect strict du délai de 12 secondes constituent les piliers du pipeline.\n\nDans le prochain article, nous couvrirons le bundling et la résolution de conflits.","\u003Ch2 id=\"pourquoi-simuler\">Pourquoi simuler ?\u003C\u002Fh2>\n\u003Cp>Dans le MEV, vous ne pouvez pas deviner — vous devez savoir exactement combien de profit une opportunité va générer, combien de gas elle consommera, et si la transaction réussira. La simulation est la seule façon d’obtenir ces réponses avant de soumettre un bundle.\u003C\u002Fp>\n\u003Ch2 id=\"fork-d-tat-avec-revm\">Fork d’état avec revm\u003C\u002Fh2>\n\u003Cp>revm est une implémentation de l’EVM en Rust, optimisée pour la vitesse. Elle peut forker l’état d’un nœud Ethereum et exécuter des transactions localement :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">use revm::{EVM, db::CacheDB, primitives::*};\n\nfn simulate_swap(\n    state: &amp;CacheDB,\n    swap_calldata: Bytes,\n    target_contract: Address,\n) -&gt; Result&lt;SimResult, Error&gt; {\n    let mut evm = EVM::new();\n    evm.database(state.clone());\n\n    evm.env.tx = TxEnv {\n        caller: bot_address(),\n        transact_to: TransactTo::Call(target_contract),\n        data: swap_calldata,\n        value: U256::ZERO,\n        gas_limit: 500_000,\n        ..Default::default()\n    };\n\n    let result = evm.transact()?;\n    Ok(SimResult {\n        gas_used: result.gas_used,\n        output: result.output,\n        success: result.is_success(),\n    })\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"recherche-binaire-du-montant-optimal\">Recherche binaire du montant optimal\u003C\u002Fh2>\n\u003Cp>La courbe profit\u002Fmontant pour un arbitrage AMM est concave — le profit augmente avec le montant jusqu’à un point optimal puis diminue. La recherche binaire est idéale :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn find_optimal_amount(\n    state: &amp;CacheDB,\n    cycle: &amp;[Pool],\n    token: Address,\n) -&gt; (U256, U256) {\n    let mut lo = U256::from(1_000_000); \u002F\u002F 0.001 ETH minimum\n    let mut hi = U256::from(100_000_000_000_000_000_000u128); \u002F\u002F 100 ETH max\n\n    for _ in 0..128 {\n        let mid = (lo + hi) \u002F 2;\n        let profit_at_mid = simulate_cycle(state, cycle, mid);\n        let profit_at_mid_plus = simulate_cycle(state, cycle, mid + lo);\n\n        if profit_at_mid_plus &gt; profit_at_mid {\n            lo = mid;\n        } else {\n            hi = mid;\n        }\n    }\n\n    let optimal = (lo + hi) \u002F 2;\n    let profit = simulate_cycle(state, cycle, optimal);\n    (optimal, profit)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"le-d-lai-de-12-secondes\">Le délai de 12 secondes\u003C\u002Fh2>\n\u003Cp>Les blocs Ethereum arrivent toutes les 12 secondes. Votre pipeline doit :\u003C\u002Fp>\n\u003Col>\n\u003Cli>Recevoir le nouveau bloc\u003C\u002Fli>\n\u003Cli>Mettre à jour l’état local\u003C\u002Fli>\n\u003Cli>Détecter les nouvelles opportunités\u003C\u002Fli>\n\u003Cli>Simuler chaque opportunité\u003C\u002Fli>\n\u003Cli>Optimiser le montant\u003C\u002Fli>\n\u003Cli>Soumettre le bundle au constructeur de blocs\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Tout cela en moins de ~6 secondes (pour laisser au constructeur le temps d’inclure votre bundle).\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">async fn block_pipeline(block: Block) {\n    let start = Instant::now();\n    let deadline = start + Duration::from_secs(6);\n\n    \u002F\u002F Mise à jour de l'état\n    let state = update_state(&amp;block).await;\n\n    \u002F\u002F Recherche d'opportunités en parallèle\n    let opportunities = find_opportunities(&amp;state).await;\n\n    for opp in opportunities {\n        if Instant::now() &gt; deadline {\n            break; \u002F\u002F Plus le temps — soumettre ce qu'on a\n        }\n\n        let (amount, profit) = find_optimal_amount(&amp;state, &amp;opp);\n        let gas_cost = estimate_gas_cost(&amp;state, &amp;opp, amount);\n\n        if profit &gt; gas_cost * 2 { \u002F\u002F Marge de sécurité 2x\n            submit_bundle(&amp;opp, amount).await;\n        }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"simulation-de-bundles\">Simulation de bundles\u003C\u002Fh2>\n\u003Cp>Un bundle MEV peut contenir plusieurs transactions ordonnées. Simulez le bundle complet, pas les transactions individuelles :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn simulate_bundle(\n    state: &amp;CacheDB,\n    transactions: &amp;[Transaction],\n) -&gt; BundleResult {\n    let mut current_state = state.clone();\n    let mut total_profit = U256::ZERO;\n    let mut total_gas = 0u64;\n\n    for tx in transactions {\n        let result = simulate_on_state(&amp;current_state, tx);\n        if !result.success {\n            return BundleResult::Failed;\n        }\n        current_state = result.new_state;\n        total_profit += result.profit;\n        total_gas += result.gas_used;\n    }\n\n    BundleResult::Success { total_profit, total_gas }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"conclusion\">Conclusion\u003C\u002Fh2>\n\u003Cp>La simulation MEV est le pont entre la détection d’opportunités et la soumission de bundles rentables. revm pour le fork d’état, la recherche binaire pour l’optimisation, et le respect strict du délai de 12 secondes constituent les piliers du pipeline.\u003C\u002Fp>\n\u003Cp>Dans le prochain article, nous couvrirons le bundling et la résolution de conflits.\u003C\u002Fp>\n","fr","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:29.123182Z","Deep EVM #15 : Simulation MEV — Recherche binaire, forks d'état et délais","Pipeline de simulation MEV en Rust : fork d'état revm, recherche binaire de montant optimal, simulation de bundles et contrainte de 12 secondes.","simulation MEV revm",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000019","MEV","mev",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000001","Rust","rust","Blockchain",[41,48,55],{"id":42,"title":43,"slug":44,"excerpt":45,"locale":12,"category_name":46,"published_at":47},"d0000000-0000-0000-0000-000000000654","WASI 0.3 et la mort des démarrages à froid : le Wasm côté serveur en production","wasi-0-3-mort-demarrages-froid-wasm-cote-serveur-production","WASI 0.3 est sorti en février 2026 avec l'async I\u002FO natif, les types stream et le support complet des sockets. Le WebAssembly côté serveur offre désormais des démarrages à froid en microsecondes, et chaque grand fournisseur cloud propose du Wasm serverless.","DevOps","2026-03-28T10:44:48.159283Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":53,"published_at":54},"d0000000-0000-0000-0000-000000000632","La stack backend moderne 2026 : Rust + PostgreSQL 18 + Wasm + eBPF","stack-backend-moderne-2026-rust-postgresql-wasm-ebpf","Quatre technologies convergent pour redefinir l'infrastructure backend en 2026 : Rust elimine l'overhead du garbage collection et reduit le nombre de conteneurs par 3, PostgreSQL 18 remplace les bases specialisees, WASI 0.3 offre des demarrages a froid en microsecondes pour les fonctions serverless, et eBPF permet l'observabilite sans instrumentation a une fraction du cout du monitoring traditionnel.","Engineering","2026-03-28T10:44:46.680187Z",{"id":56,"title":57,"slug":58,"excerpt":59,"locale":12,"category_name":39,"published_at":60},"d0000000-0000-0000-0000-000000000608","La couche d'interoperabilite Ethereum : comment 55+ L2 deviennent une seule chaine","couche-interoperabilite-ethereum-55-l2-deviennent-une-seule-chaine","Ethereum compte 55+ rollups Layer 2, fragmentant la liquidite et l'experience utilisateur. La couche d'interoperabilite Ethereum — combinant messagerie cross-rollup, sequenceurs partages et based rollups — vise a les unifier en un reseau composable unique.","2026-03-28T10:44:45.078068Z",{"id":13,"name":62,"slug":63,"bio":64,"photo_url":19,"linkedin":19,"role":65,"created_at":66,"updated_at":66},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]