[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-16-bundling-resolucion-conflictos-empaquetado":3},{"article":4,"author":60},{"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},"d8000000-0000-0000-0000-000000000116","a0000000-0000-0000-0000-000000000082","Deep EVM #16: Bundling y Resolución de Conflictos — Empaquetando Transacciones Rentables","deep-evm-16-bundling-resolucion-conflictos-empaquetado","Aprende a construir bundles MEV óptimos: detección de conflictos entre transacciones, algoritmos de empaquetado, gestión de pago al builder y estrategias de envío multi-builder.","## El problema del bundling\n\nUn searcher de MEV puede encontrar docenas de oportunidades rentables en un solo bloque. El desafío es empaquetarlas en un bundle coherente:\n\n- Las transacciones deben ejecutarse en orden específico\n- Algunas transacciones conflictan (acceden al mismo estado)\n- El bundle debe pagar suficiente al builder para ser incluido\n- El coste total de gas debe dejar margen de beneficio\n\n## Detección de conflictos\n\nDos transacciones conflictan cuando una lee o escribe estado que la otra escribe. Para detectar conflictos, rastreamos los conjuntos de lectura\u002Fescritura de cada transacción:\n\n```rust\nstruct AccessSet {\n    reads: HashSet\u003C(Address, U256)>,  \u002F\u002F (contrato, slot)\n    writes: HashSet\u003C(Address, U256)>,\n}\n\nfn conflicts(a: &AccessSet, b: &AccessSet) -> bool {\n    \u002F\u002F Conflicto si A escribe algo que B lee o escribe,\n    \u002F\u002F o si B escribe algo que A lee\n    !a.writes.is_disjoint(&b.reads)\n        || !a.writes.is_disjoint(&b.writes)\n        || !b.writes.is_disjoint(&a.reads)\n}\n```\n\nrevm puede capturar los access sets durante la simulación usando un inspector personalizado.\n\n## Grafo de conflictos\n\nCon N oportunidades, construimos un grafo de conflictos:\n\n```rust\nstruct ConflictGraph {\n    opportunities: Vec\u003COpportunity>,\n    conflicts: Vec\u003CVec\u003Cbool>>, \u002F\u002F matriz de adyacencia\n}\n\nimpl ConflictGraph {\n    fn build(opps: Vec\u003COpportunity>, db: &CacheDB) -> Self {\n        let n = opps.len();\n        let mut conflicts = vec![vec![false; n]; n];\n        \n        for i in 0..n {\n            for j in (i+1)..n {\n                if access_sets_conflict(&opps[i], &opps[j]) {\n                    conflicts[i][j] = true;\n                    conflicts[j][i] = true;\n                }\n            }\n        }\n        \n        Self { opportunities: opps, conflicts }\n    }\n}\n```\n\n## Algoritmo de empaquetado\n\nEl empaquetado óptimo es NP-hard (es una variante del problema de conjunto independiente máximo con pesos). Usamos una heurística greedy:\n\n```rust\nfn greedy_pack(\n    graph: &ConflictGraph,\n) -> Vec\u003Cusize> {\n    \u002F\u002F Ordenar por beneficio descendente\n    let mut indices: Vec\u003Cusize> = (0..graph.opportunities.len()).collect();\n    indices.sort_by(|&a, &b| {\n        graph.opportunities[b].profit\n            .cmp(&graph.opportunities[a].profit)\n    });\n    \n    let mut selected = Vec::new();\n    let mut excluded = HashSet::new();\n    \n    for &idx in &indices {\n        if excluded.contains(&idx) {\n            continue;\n        }\n        \n        selected.push(idx);\n        \n        \u002F\u002F Excluir todas las oportunidades que conflictan\n        for (other, &has_conflict) in graph.conflicts[idx].iter().enumerate() {\n            if has_conflict {\n                excluded.insert(other);\n            }\n        }\n    }\n    \n    selected\n}\n```\n\n## Ordenamiento topológico\n\nUna vez seleccionadas las oportunidades sin conflictos, debemos ordenarlas correctamente. Algunas pueden tener dependencias (e.g., un swap que genera tokens necesarios para otro):\n\n```rust\nfn topological_sort(\n    selected: &[usize],\n    dependencies: &HashMap\u003Cusize, Vec\u003Cusize>>,\n) -> Vec\u003Cusize> {\n    let mut result = Vec::new();\n    let mut visited = HashSet::new();\n    \n    fn dfs(\n        node: usize,\n        deps: &HashMap\u003Cusize, Vec\u003Cusize>>,\n        visited: &mut HashSet\u003Cusize>,\n        result: &mut Vec\u003Cusize>,\n    ) {\n        if visited.contains(&node) { return; }\n        visited.insert(node);\n        if let Some(parents) = deps.get(&node) {\n            for &parent in parents {\n                dfs(parent, deps, visited, result);\n            }\n        }\n        result.push(node);\n    }\n    \n    for &idx in selected {\n        dfs(idx, dependencies, &mut visited, &mut result);\n    }\n    result\n}\n```\n\n## Pago al builder\n\nEl bundle debe incluir un pago al builder para ser competitivo. La estrategia de pago depende del beneficio total y la competencia:\n\n```rust\nfn calculate_builder_payment(\n    total_profit: U256,\n    gas_cost: U256,\n    competition_level: f64, \u002F\u002F 0.0 a 1.0\n) -> U256 {\n    let net_profit = total_profit - gas_cost;\n    \n    \u002F\u002F Porcentaje del beneficio neto que va al builder\n    \u002F\u002F Alta competencia = mayor porcentaje\n    let builder_share = match competition_level {\n        x if x > 0.8 => 0.95, \u002F\u002F 95% al builder en alta competencia\n        x if x > 0.5 => 0.80,\n        x if x > 0.2 => 0.60,\n        _ => 0.40,\n    };\n    \n    \u002F\u002F Implementar como transferencia de ETH al coinbase\n    net_profit * U256::from((builder_share * 100.0) as u64) \u002F U256::from(100)\n}\n```\n\n## Envío multi-builder\n\nEnviar el bundle a múltiples builders maximiza la probabilidad de inclusión:\n\n```rust\nasync fn submit_to_builders(\n    bundle: &Bundle,\n    builders: &[BuilderEndpoint],\n) -> Vec\u003CResult\u003CSubmitResponse, Error>> {\n    let futures: Vec\u003C_> = builders.iter().map(|builder| {\n        submit_bundle(bundle, builder)\n    }).collect();\n    \n    futures::future::join_all(futures).await\n}\n```\n\nBuilders principales:\n- Flashbots Builder (relay.flashbots.net)\n- BloXroute (mev.api.blxrbdn.com)\n- Titan Builder\n- Beaver Build\n\n## Conclusión\n\nEl bundling efectivo convierte oportunidades individuales de MEV en bloques rentables. La detección de conflictos basada en access sets, el empaquetado greedy, el ordenamiento topológico, y la estrategia de pago al builder son las piezas clave. El envío multi-builder maximiza la probabilidad de inclusión, y el monitoreo continuo permite ajustar la estrategia competitiva.","\u003Ch2 id=\"el-problema-del-bundling\">El problema del bundling\u003C\u002Fh2>\n\u003Cp>Un searcher de MEV puede encontrar docenas de oportunidades rentables en un solo bloque. El desafío es empaquetarlas en un bundle coherente:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Las transacciones deben ejecutarse en orden específico\u003C\u002Fli>\n\u003Cli>Algunas transacciones conflictan (acceden al mismo estado)\u003C\u002Fli>\n\u003Cli>El bundle debe pagar suficiente al builder para ser incluido\u003C\u002Fli>\n\u003Cli>El coste total de gas debe dejar margen de beneficio\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"detecci-n-de-conflictos\">Detección de conflictos\u003C\u002Fh2>\n\u003Cp>Dos transacciones conflictan cuando una lee o escribe estado que la otra escribe. Para detectar conflictos, rastreamos los conjuntos de lectura\u002Fescritura de cada transacción:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">struct AccessSet {\n    reads: HashSet&lt;(Address, U256)&gt;,  \u002F\u002F (contrato, slot)\n    writes: HashSet&lt;(Address, U256)&gt;,\n}\n\nfn conflicts(a: &amp;AccessSet, b: &amp;AccessSet) -&gt; bool {\n    \u002F\u002F Conflicto si A escribe algo que B lee o escribe,\n    \u002F\u002F o si B escribe algo que A lee\n    !a.writes.is_disjoint(&amp;b.reads)\n        || !a.writes.is_disjoint(&amp;b.writes)\n        || !b.writes.is_disjoint(&amp;a.reads)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>revm puede capturar los access sets durante la simulación usando un inspector personalizado.\u003C\u002Fp>\n\u003Ch2 id=\"grafo-de-conflictos\">Grafo de conflictos\u003C\u002Fh2>\n\u003Cp>Con N oportunidades, construimos un grafo de conflictos:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">struct ConflictGraph {\n    opportunities: Vec&lt;Opportunity&gt;,\n    conflicts: Vec&lt;Vec&lt;bool&gt;&gt;, \u002F\u002F matriz de adyacencia\n}\n\nimpl ConflictGraph {\n    fn build(opps: Vec&lt;Opportunity&gt;, db: &amp;CacheDB) -&gt; Self {\n        let n = opps.len();\n        let mut conflicts = vec![vec![false; n]; n];\n        \n        for i in 0..n {\n            for j in (i+1)..n {\n                if access_sets_conflict(&amp;opps[i], &amp;opps[j]) {\n                    conflicts[i][j] = true;\n                    conflicts[j][i] = true;\n                }\n            }\n        }\n        \n        Self { opportunities: opps, conflicts }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"algoritmo-de-empaquetado\">Algoritmo de empaquetado\u003C\u002Fh2>\n\u003Cp>El empaquetado óptimo es NP-hard (es una variante del problema de conjunto independiente máximo con pesos). Usamos una heurística greedy:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn greedy_pack(\n    graph: &amp;ConflictGraph,\n) -&gt; Vec&lt;usize&gt; {\n    \u002F\u002F Ordenar por beneficio descendente\n    let mut indices: Vec&lt;usize&gt; = (0..graph.opportunities.len()).collect();\n    indices.sort_by(|&amp;a, &amp;b| {\n        graph.opportunities[b].profit\n            .cmp(&amp;graph.opportunities[a].profit)\n    });\n    \n    let mut selected = Vec::new();\n    let mut excluded = HashSet::new();\n    \n    for &amp;idx in &amp;indices {\n        if excluded.contains(&amp;idx) {\n            continue;\n        }\n        \n        selected.push(idx);\n        \n        \u002F\u002F Excluir todas las oportunidades que conflictan\n        for (other, &amp;has_conflict) in graph.conflicts[idx].iter().enumerate() {\n            if has_conflict {\n                excluded.insert(other);\n            }\n        }\n    }\n    \n    selected\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"ordenamiento-topol-gico\">Ordenamiento topológico\u003C\u002Fh2>\n\u003Cp>Una vez seleccionadas las oportunidades sin conflictos, debemos ordenarlas correctamente. Algunas pueden tener dependencias (e.g., un swap que genera tokens necesarios para otro):\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn topological_sort(\n    selected: &amp;[usize],\n    dependencies: &amp;HashMap&lt;usize, Vec&lt;usize&gt;&gt;,\n) -&gt; Vec&lt;usize&gt; {\n    let mut result = Vec::new();\n    let mut visited = HashSet::new();\n    \n    fn dfs(\n        node: usize,\n        deps: &amp;HashMap&lt;usize, Vec&lt;usize&gt;&gt;,\n        visited: &amp;mut HashSet&lt;usize&gt;,\n        result: &amp;mut Vec&lt;usize&gt;,\n    ) {\n        if visited.contains(&amp;node) { return; }\n        visited.insert(node);\n        if let Some(parents) = deps.get(&amp;node) {\n            for &amp;parent in parents {\n                dfs(parent, deps, visited, result);\n            }\n        }\n        result.push(node);\n    }\n    \n    for &amp;idx in selected {\n        dfs(idx, dependencies, &amp;mut visited, &amp;mut result);\n    }\n    result\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"pago-al-builder\">Pago al builder\u003C\u002Fh2>\n\u003Cp>El bundle debe incluir un pago al builder para ser competitivo. La estrategia de pago depende del beneficio total y la competencia:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn calculate_builder_payment(\n    total_profit: U256,\n    gas_cost: U256,\n    competition_level: f64, \u002F\u002F 0.0 a 1.0\n) -&gt; U256 {\n    let net_profit = total_profit - gas_cost;\n    \n    \u002F\u002F Porcentaje del beneficio neto que va al builder\n    \u002F\u002F Alta competencia = mayor porcentaje\n    let builder_share = match competition_level {\n        x if x &gt; 0.8 =&gt; 0.95, \u002F\u002F 95% al builder en alta competencia\n        x if x &gt; 0.5 =&gt; 0.80,\n        x if x &gt; 0.2 =&gt; 0.60,\n        _ =&gt; 0.40,\n    };\n    \n    \u002F\u002F Implementar como transferencia de ETH al coinbase\n    net_profit * U256::from((builder_share * 100.0) as u64) \u002F U256::from(100)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"env-o-multi-builder\">Envío multi-builder\u003C\u002Fh2>\n\u003Cp>Enviar el bundle a múltiples builders maximiza la probabilidad de inclusión:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">async fn submit_to_builders(\n    bundle: &amp;Bundle,\n    builders: &amp;[BuilderEndpoint],\n) -&gt; Vec&lt;Result&lt;SubmitResponse, Error&gt;&gt; {\n    let futures: Vec&lt;_&gt; = builders.iter().map(|builder| {\n        submit_bundle(bundle, builder)\n    }).collect();\n    \n    futures::future::join_all(futures).await\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Builders principales:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Flashbots Builder (relay.flashbots.net)\u003C\u002Fli>\n\u003Cli>BloXroute (mev.api.blxrbdn.com)\u003C\u002Fli>\n\u003Cli>Titan Builder\u003C\u002Fli>\n\u003Cli>Beaver Build\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"conclusi-n\">Conclusión\u003C\u002Fh2>\n\u003Cp>El bundling efectivo convierte oportunidades individuales de MEV en bloques rentables. La detección de conflictos basada en access sets, el empaquetado greedy, el ordenamiento topológico, y la estrategia de pago al builder son las piezas clave. El envío multi-builder maximiza la probabilidad de inclusión, y el monitoreo continuo permite ajustar la estrategia competitiva.\u003C\u002Fp>\n","es","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:31.407743Z","Deep EVM #16: Bundling y Resolución de Conflictos — Empaquetando Transacciones MEV","Construye bundles MEV óptimos: detección de conflictos, empaquetado greedy, pago al builder y envío multi-builder.","MEV bundling resolución conflictos",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000019","MEV","mev","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000001","Rust","rust",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000013","Security","security",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000009","Web3","web3","Blockchain",[41,48,54],{"id":42,"title":43,"slug":44,"excerpt":45,"locale":12,"category_name":46,"published_at":47},"d0000000-0000-0000-0000-000000000683","Por qué Bali se está convirtiendo en el hub de impact-tech del Sudeste Asiático en 2026","por-que-bali-hub-impact-tech-sudeste-asiatico-2026","Bali ocupa el puesto 16 entre los ecosistemas startup del Sudeste Asiático. Con una concentración creciente de constructores Web3, startups de AI sostenible y empresas de eco-travel tech, la isla se consolida como capital de impact-tech de la región.","Ingeniería","2026-03-28T10:44:49.926489Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":46,"published_at":53},"d0000000-0000-0000-0000-000000000682","El mosaico de protección de datos de ASEAN: checklist de cumplimiento para desarrolladores","mosaico-proteccion-datos-asean-checklist-cumplimiento-desarrolladores","Siete países de ASEAN tienen ahora leyes integrales de protección de datos, cada una con diferentes modelos de consentimiento, requisitos de localización y estructuras de sanciones. Un checklist práctico de cumplimiento para desarrolladores.","2026-03-28T10:44:49.919345Z",{"id":55,"title":56,"slug":57,"excerpt":58,"locale":12,"category_name":46,"published_at":59},"d0000000-0000-0000-0000-000000000681","La transformación digital de 29 mil millones de dólares de Indonesia: oportunidades para empresas de software","transformacion-digital-29-mil-millones-dolares-indonesia-oportunidades-empresas-software","El mercado de servicios IT de Indonesia alcanzará los 29.030 millones de dólares en 2026, frente a los 24.370 millones de 2025. La infraestructura cloud, la AI, el comercio electrónico y los centros de datos impulsan el crecimiento más rápido del Sudeste Asiático.","2026-03-28T10:44:49.897658Z",{"id":13,"name":61,"slug":62,"bio":63,"photo_url":19,"linkedin":19,"role":64,"created_at":65,"updated_at":65},"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"]