[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-14-bina-bahith-dawrat-murajaha-bahth-umq-rasm-bayani":3},{"article":4,"author":57},{"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":35,"related_articles":36},"d9000000-0000-0000-0000-000000000114","a0000000-0000-0000-0000-000000000092","Deep EVM #14: بناء باحث دورات المراجحة — البحث بالعمق أولاً على رسم بياني للمجمعات","deep-evm-14-bina-bahith-dawrat-murajaha-bahth-umq-rasm-bayani","بناء محرك للعثور على فرص المراجحة الدورية باستخدام البحث بالعمق أولاً (DFS) على رسم بياني لمجمعات السيولة، مع تحسين المسار وحساب الربح.","## مشكلة المراجحة الدورية\n\nالمراجحة الدورية هي العثور على مسار عبر عدة مجمعات سيولة يبدأ وينتهي بنفس الرمز مع ربح صافٍ. على سبيل المثال:\n\n```\nETH → USDC (Uniswap V2)\nUSDC → DAI (Curve)\nDAI → ETH (Sushiswap)\n```\n\nإذا كان الناتج النهائي أكثر ETH مما بدأت به (بعد خصم الغاز)، فهناك فرصة مراجحة.\n\n## نمذجة المشكلة كرسم بياني\n\nكل رمز هو عقدة. كل مجمع سيولة هو حافة (أو أكثر) بين الرموز التي يدعمها:\n\n```rust\nstruct Pool {\n    address: Address,\n    token0: Address,\n    token1: Address,\n    reserve0: U256,\n    reserve1: U256,\n    fee: u32,  \u002F\u002F بالنقاط الأساسية\n}\n\nstruct Graph {\n    adjacency: HashMap\u003CAddress, Vec\u003CEdge>>,\n}\n\nstruct Edge {\n    pool: Pool,\n    target_token: Address,\n}\n```\n\n## خوارزمية DFS\n\nالبحث بالعمق أولاً يستكشف كل المسارات الممكنة من رمز البداية:\n\n```rust\nfn find_cycles(\n    graph: &Graph,\n    start: Address,\n    current: Address,\n    path: &mut Vec\u003CEdge>,\n    visited: &mut HashSet\u003CAddress>,\n    cycles: &mut Vec\u003CVec\u003CEdge>>,\n    max_depth: usize,\n) {\n    if path.len() > max_depth {\n        return;\n    }\n    \n    if path.len() >= 2 && current == start {\n        cycles.push(path.clone());\n        return;\n    }\n    \n    if visited.contains(&current) && current != start {\n        return;\n    }\n    visited.insert(current);\n    \n    if let Some(edges) = graph.adjacency.get(&current) {\n        for edge in edges {\n            path.push(edge.clone());\n            find_cycles(\n                graph, start, edge.target_token,\n                path, visited, cycles, max_depth,\n            );\n            path.pop();\n        }\n    }\n    visited.remove(&current);\n}\n```\n\n## حساب الربح\n\nلكل دورة مكتشفة، نحسب الناتج المتوقع:\n\n```rust\nfn calculate_output(\n    amount_in: U256,\n    reserve_in: U256,\n    reserve_out: U256,\n    fee_bps: u32,\n) -> U256 {\n    let amount_with_fee = amount_in * (10000 - fee_bps);\n    let numerator = amount_with_fee * reserve_out;\n    let denominator = reserve_in * 10000 + amount_with_fee;\n    numerator \u002F denominator\n}\n\nfn simulate_cycle(cycle: &[Edge], amount_in: U256) -> U256 {\n    let mut current = amount_in;\n    for edge in cycle {\n        current = calculate_output(\n            current,\n            edge.pool.reserve_in(),\n            edge.pool.reserve_out(),\n            edge.pool.fee,\n        );\n    }\n    current  \u002F\u002F إذا > amount_in، هناك ربح\n}\n```\n\n## تحسين المبلغ الأمثل\n\nالمبلغ الأمثل ليس دائماً الأقصى. استخدم البحث الثنائي:\n\n```rust\nfn find_optimal_amount(\n    cycle: &[Edge],\n    min: U256,\n    max: U256,\n) -> (U256, U256) {\n    let mut lo = min;\n    let mut hi = max;\n    let mut best_amount = min;\n    let mut best_profit = U256::ZERO;\n    \n    for _ in 0..64 {\n        let mid = (lo + hi) \u002F 2;\n        let output = simulate_cycle(cycle, mid);\n        let profit = output.saturating_sub(mid);\n        \n        if profit > best_profit {\n            best_profit = profit;\n            best_amount = mid;\n        }\n        \n        \u002F\u002F فحص الاتجاه\n        let output_plus = simulate_cycle(cycle, mid + 1);\n        if output_plus.saturating_sub(mid + 1) > profit {\n            lo = mid;\n        } else {\n            hi = mid;\n        }\n    }\n    (best_amount, best_profit)\n}\n```\n\n## الأداء\n\nالتحديات الرئيسية:\n- **عدد المسارات** — رسم بياني بـ 1000 رمز و5000 مجمع يولد ملايين الدورات المحتملة\n- **قيد الوقت** — 12 ثانية بين الكتل على إيثيريوم\n- **تحديث الحالة** — الاحتياطيات تتغير مع كل كتلة\n\nالتحسينات:\n1. **التقليم المبكر** — تجاهل المسارات التي لا يمكنها تحقيق ربح\n2. **التوازي** — توزيع البحث على عدة خيوط باستخدام rayon\n3. **التخزين المؤقت** — تخبئة حسابات المخرجات المتكررة\n4. **تحديد العمق** — الحد من طول الدورة (عادة 2-4 قفزات)\n\n## الخلاصة\n\nباحث دورات المراجحة هو قلب أي روبوت MEV مراجحة. المكونات الأساسية: رسم بياني للمجمعات، DFS للعثور على الدورات، محاكاة لحساب الربح، وبحث ثنائي للمبلغ الأمثل. الباقي تحسين.","\u003Ch2 id=\"\">مشكلة المراجحة الدورية\u003C\u002Fh2>\n\u003Cp>المراجحة الدورية هي العثور على مسار عبر عدة مجمعات سيولة يبدأ وينتهي بنفس الرمز مع ربح صافٍ. على سبيل المثال:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>ETH → USDC (Uniswap V2)\nUSDC → DAI (Curve)\nDAI → ETH (Sushiswap)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>إذا كان الناتج النهائي أكثر ETH مما بدأت به (بعد خصم الغاز)، فهناك فرصة مراجحة.\u003C\u002Fp>\n\u003Ch2 id=\"\">نمذجة المشكلة كرسم بياني\u003C\u002Fh2>\n\u003Cp>كل رمز هو عقدة. كل مجمع سيولة هو حافة (أو أكثر) بين الرموز التي يدعمها:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">struct Pool {\n    address: Address,\n    token0: Address,\n    token1: Address,\n    reserve0: U256,\n    reserve1: U256,\n    fee: u32,  \u002F\u002F بالنقاط الأساسية\n}\n\nstruct Graph {\n    adjacency: HashMap&lt;Address, Vec&lt;Edge&gt;&gt;,\n}\n\nstruct Edge {\n    pool: Pool,\n    target_token: Address,\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"dfs\">خوارزمية DFS\u003C\u002Fh2>\n\u003Cp>البحث بالعمق أولاً يستكشف كل المسارات الممكنة من رمز البداية:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn find_cycles(\n    graph: &amp;Graph,\n    start: Address,\n    current: Address,\n    path: &amp;mut Vec&lt;Edge&gt;,\n    visited: &amp;mut HashSet&lt;Address&gt;,\n    cycles: &amp;mut Vec&lt;Vec&lt;Edge&gt;&gt;,\n    max_depth: usize,\n) {\n    if path.len() &gt; max_depth {\n        return;\n    }\n    \n    if path.len() &gt;= 2 &amp;&amp; current == start {\n        cycles.push(path.clone());\n        return;\n    }\n    \n    if visited.contains(&amp;current) &amp;&amp; current != start {\n        return;\n    }\n    visited.insert(current);\n    \n    if let Some(edges) = graph.adjacency.get(&amp;current) {\n        for edge in edges {\n            path.push(edge.clone());\n            find_cycles(\n                graph, start, edge.target_token,\n                path, visited, cycles, max_depth,\n            );\n            path.pop();\n        }\n    }\n    visited.remove(&amp;current);\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">حساب الربح\u003C\u002Fh2>\n\u003Cp>لكل دورة مكتشفة، نحسب الناتج المتوقع:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn calculate_output(\n    amount_in: U256,\n    reserve_in: U256,\n    reserve_out: U256,\n    fee_bps: u32,\n) -&gt; U256 {\n    let amount_with_fee = amount_in * (10000 - fee_bps);\n    let numerator = amount_with_fee * reserve_out;\n    let denominator = reserve_in * 10000 + amount_with_fee;\n    numerator \u002F denominator\n}\n\nfn simulate_cycle(cycle: &amp;[Edge], amount_in: U256) -&gt; U256 {\n    let mut current = amount_in;\n    for edge in cycle {\n        current = calculate_output(\n            current,\n            edge.pool.reserve_in(),\n            edge.pool.reserve_out(),\n            edge.pool.fee,\n        );\n    }\n    current  \u002F\u002F إذا &gt; amount_in، هناك ربح\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">تحسين المبلغ الأمثل\u003C\u002Fh2>\n\u003Cp>المبلغ الأمثل ليس دائماً الأقصى. استخدم البحث الثنائي:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn find_optimal_amount(\n    cycle: &amp;[Edge],\n    min: U256,\n    max: U256,\n) -&gt; (U256, U256) {\n    let mut lo = min;\n    let mut hi = max;\n    let mut best_amount = min;\n    let mut best_profit = U256::ZERO;\n    \n    for _ in 0..64 {\n        let mid = (lo + hi) \u002F 2;\n        let output = simulate_cycle(cycle, mid);\n        let profit = output.saturating_sub(mid);\n        \n        if profit &gt; best_profit {\n            best_profit = profit;\n            best_amount = mid;\n        }\n        \n        \u002F\u002F فحص الاتجاه\n        let output_plus = simulate_cycle(cycle, mid + 1);\n        if output_plus.saturating_sub(mid + 1) &gt; profit {\n            lo = mid;\n        } else {\n            hi = mid;\n        }\n    }\n    (best_amount, best_profit)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">الأداء\u003C\u002Fh2>\n\u003Cp>التحديات الرئيسية:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>عدد المسارات\u003C\u002Fstrong> — رسم بياني بـ 1000 رمز و5000 مجمع يولد ملايين الدورات المحتملة\u003C\u002Fli>\n\u003Cli>\u003Cstrong>قيد الوقت\u003C\u002Fstrong> — 12 ثانية بين الكتل على إيثيريوم\u003C\u002Fli>\n\u003Cli>\u003Cstrong>تحديث الحالة\u003C\u002Fstrong> — الاحتياطيات تتغير مع كل كتلة\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>التحسينات:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>التقليم المبكر\u003C\u002Fstrong> — تجاهل المسارات التي لا يمكنها تحقيق ربح\u003C\u002Fli>\n\u003Cli>\u003Cstrong>التوازي\u003C\u002Fstrong> — توزيع البحث على عدة خيوط باستخدام rayon\u003C\u002Fli>\n\u003Cli>\u003Cstrong>التخزين المؤقت\u003C\u002Fstrong> — تخبئة حسابات المخرجات المتكررة\u003C\u002Fli>\n\u003Cli>\u003Cstrong>تحديد العمق\u003C\u002Fstrong> — الحد من طول الدورة (عادة 2-4 قفزات)\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">الخلاصة\u003C\u002Fh2>\n\u003Cp>باحث دورات المراجحة هو قلب أي روبوت MEV مراجحة. المكونات الأساسية: رسم بياني للمجمعات، DFS للعثور على الدورات، محاكاة لحساب الربح، وبحث ثنائي للمبلغ الأمثل. الباقي تحسين.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:32.492012Z","Deep EVM #14: بناء باحث دورات المراجحة — DFS على رسم بياني للمجمعات","بناء باحث دورات المراجحة باستخدام DFS على رسم بياني لمجمعات السيولة مع تحسين المسار وحساب الربح.","MEV مراجحة Rust",null,"index, follow",[22,27,31],{"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-000000000019","MEV","mev",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000001","Rust","rust","بلوكتشين",[37,44,51],{"id":38,"title":39,"slug":40,"excerpt":41,"locale":12,"category_name":42,"published_at":43},"d0000000-0000-0000-0000-000000000663","WASI 0.3 ونهاية البدء البارد: Wasm من جانب الخادم في الإنتاج","wasi-0-3-nihayat-albad-albarid-wasm-janib-alkhadim-intaj","صدر WASI 0.3 في فبراير 2026 مع async I\u002FO أصلي وأنواع stream ودعم كامل للمقابس. يوفر WebAssembly من جانب الخادم الآن بدءاً بارداً بالميكروثانية، وكل مزود سحابي رئيسي يقدم Wasm بدون خادم.","DevOps","2026-03-28T10:44:48.694830Z",{"id":45,"title":46,"slug":47,"excerpt":48,"locale":12,"category_name":49,"published_at":50},"d0000000-0000-0000-0000-000000000641","حزمة الخلفية الحديثة 2026: Rust + PostgreSQL 18 + Wasm + eBPF","huzmat-alkhalfiyya-alhaditha-2026-rust-postgresql-wasm-ebpf","أربع تقنيات تتقارب لإعادة تعريف البنية التحتية للخلفية في 2026: Rust يزيل عبء جمع القمامة ويقلل الحاويات بمقدار 3 أضعاف، PostgreSQL 18 يحل محل قواعد البيانات المتخصصة، WASI 0.3 يوفر بدء تشغيل بالميكروثانية للدوال بدون خادم، وeBPF يمكّن المراقبة بدون أدوات بجزء بسيط من تكلفة المراقبة التقليدية.","Engineering","2026-03-28T10:44:47.292897Z",{"id":52,"title":53,"slug":54,"excerpt":55,"locale":12,"category_name":35,"published_at":56},"d0000000-0000-0000-0000-000000000617","طبقة التشغيل البيني لـ Ethereum: كيف تصبح 55+ سلسلة L2 سلسلة واحدة","tabaqat-altashghil-albaini-ethereum-55-l2-silsila-wahida","يملك Ethereum اكثر من 55 rollup من الطبقة الثانية، مما يجزئ السيولة وتجربة المستخدم. طبقة التشغيل البيني لـ Ethereum — الجمع بين الرسائل عبر الـ rollups والمتسلسلات المشتركة والـ based rollups — تهدف الى توحيدها في شبكة قابلة للتركيب واحدة.","2026-03-28T10:44:45.626845Z",{"id":13,"name":58,"slug":59,"bio":60,"photo_url":19,"linkedin":19,"role":61,"created_at":62,"updated_at":62},"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"]