Langsung ke konten utama
RekayasaMar 28, 2026

Deep EVM #16: Bundling dan Resolusi Konflik — Mengemas Transaksi Menguntungkan

OS
Open Soft Team

Engineering Team

Dari Peluang ke Bundle

Setelah menemukan dan mensimulasikan peluang MEV, langkah terakhir adalah mengemasnya ke dalam bundle transaksi dan mengirimnya ke pembangun block. Proses ini bukan semudah mengirim transaksi — ada konflik state, persaingan dengan pencari lain, dan strategi bidding yang harus diperhatikan.

Apa Itu Bundle MEV?

Bundle adalah kumpulan transaksi yang harus dieksekusi secara berurutan dan atomik — semua berhasil atau semua gagal. Bundle dikirim ke pembangun block, bukan ke mempool publik.

struct MevBundle {
    transactions: Vec<SignedTransaction>,
    block_number: u64,
    min_timestamp: Option<u64>,
    max_timestamp: Option<u64>,
    reverting_tx_hashes: Vec<B256>, // TX yang boleh revert
}

Komponen bundle:

  • Transaksi berurutan — Urutan eksekusi dijamin
  • Target block — Bundle hanya valid untuk block tertentu
  • Atomisitas — Jika satu transaksi gagal, seluruh bundle dibatalkan

Deteksi Konflik State

Dua peluang MEV berkonflik ketika mereka menyentuh state yang sama. Misalnya, dua arbitrase yang keduanya swap di pool yang sama:

#[derive(Hash, Eq, PartialEq)]
enum StateKey {
    StorageSlot(Address, U256),
    Balance(Address),
}

struct StateAccess {
    reads: HashSet<StateKey>,
    writes: HashSet<StateKey>,
}

fn conflicts(a: &StateAccess, b: &StateAccess) -> bool {
    // Konflik jika satu menulis apa yang lain baca atau tulis
    !a.writes.is_disjoint(&b.reads)
        || !a.writes.is_disjoint(&b.writes)
        || !a.reads.is_disjoint(&b.writes)
}

Deteksi konflik dilakukan selama simulasi — revm melacak semua akses storage.

Resolusi Konflik

Ketika peluang berkonflik, Anda harus memilih mana yang disertakan:

Strategi 1: Greedy by Profit

Pilih peluang dengan profit tertinggi, tandai yang berkonflik sebagai diblokir, lanjut:

fn resolve_greedy(opportunities: &mut Vec<Opportunity>) -> Vec<Opportunity> {
    // Urutkan berdasarkan profit (terbesar dulu)
    opportunities.sort_by(|a, b| b.profit.cmp(&a.profit));
    
    let mut selected = Vec::new();
    let mut blocked_states = HashSet::new();
    
    for opp in opportunities {
        if opp.state_access.writes.is_disjoint(&blocked_states)
            && opp.state_access.reads.is_disjoint(&blocked_states)
        {
            blocked_states.extend(opp.state_access.writes.iter().cloned());
            blocked_states.extend(opp.state_access.reads.iter().cloned());
            selected.push(opp.clone());
        }
    }
    
    selected
}

Strategi 2: Simulasi Kombinatorial

Untuk sejumlah kecil peluang, simulasikan semua kombinasi yang tidak berkonflik dan pilih yang memaksimalkan total profit:

fn resolve_optimal(
    opportunities: &[Opportunity],
    db: &CacheDB<impl DatabaseRef>,
) -> Vec<Opportunity> {
    let non_conflicting = find_independent_sets(opportunities);
    
    let mut best_set = Vec::new();
    let mut best_profit = U256::ZERO;
    
    for set in non_conflicting {
        let mut sim_db = db.clone();
        let total = simulate_set(&mut sim_db, &set);
        
        if total > best_profit {
            best_profit = total;
            best_set = set;
        }
    }
    
    best_set
}

Strategi Bidding

Pembangun block menerima bundle dari banyak pencari. Untuk memastikan bundle Anda disertakan, Anda perlu menawar cukup tinggi:

Tip sebagai Persentase Profit

fn calculate_tip(
    gross_profit: U256,
    gas_cost: U256,
    tip_percentage: u64, // 80-95%
) -> U256 {
    let net_profit = gross_profit - gas_cost;
    net_profit * U256::from(tip_percentage) / U256::from(100)
}

Pencari MEV kompetitif biasanya memberikan 85-95% profit sebagai tip ke pembangun. Margin tipis ini masih menguntungkan karena volume tinggi.

Transfer ETH untuk Tip

Tip dikirim sebagai transfer ETH ke coinbase (alamat pembangun block):

fn create_tip_transaction(
    searcher: Address,
    tip_amount: U256,
    nonce: u64,
) -> Transaction {
    Transaction {
        from: searcher,
        to: Address::ZERO, // Diganti dengan coinbase saat runtime
        value: tip_amount,
        data: Bytes::new(),
        gas_limit: 21_000,
        nonce,
        ..Default::default()
    }
}

Mengirim Bundle via Flashbots

use reqwest::Client;

async fn send_bundle(
    client: &Client,
    bundle: &MevBundle,
    signer: &LocalWallet,
) -> Result<B256, Error> {
    let payload = json!({
        "jsonrpc": "2.0",
        "method": "eth_sendBundle",
        "params": [{
            "txs": bundle.transactions.iter()
                .map(|tx| format!("0x{}", hex::encode(tx.rlp())))
                .collect::<Vec<_>>(),
            "blockNumber": format!("0x{:x}", bundle.block_number),
        }],
        "id": 1,
    });
    
    let signature = sign_payload(signer, &payload).await?;
    
    let response = client
        .post("https://relay.flashbots.net")
        .header("X-Flashbots-Signature", signature)
        .json(&payload)
        .send()
        .await?;
    
    let result: JsonRpcResponse = response.json().await?;
    Ok(result.result)
}

Pipeline Lengkap

Alur lengkap dari deteksi hingga pengiriman:

1. Event listener mendeteksi perubahan state
   |
2. Pencari siklus menemukan peluang
   |
3. Simulator memverifikasi dan mengoptimasi
   |
4. Resolver menangani konflik
   |
5. Bundler mengemas transaksi + tip
   |
6. Sender mengirim ke Flashbots/pembangun
   |
7. Pembangun menyertakan di block (atau tidak)

Seluruh pipeline harus selesai dalam 2-4 detik untuk kompetitif.

Monitoring dan Analitik

struct BundleMetrics {
    bundles_sent: u64,
    bundles_included: u64,
    bundles_reverted: u64,
    total_profit: U256,
    total_tips_paid: U256,
    avg_inclusion_rate: f64,
}

Track:

  • Inclusion rate — Berapa persen bundle Anda disertakan? Di bawah 20% berarti tip terlalu rendah atau timing terlalu lambat.
  • Revert rate — Bundle yang revert mengindikasikan simulasi yang tidak akurat.
  • Profit per gas — Metrik efisiensi yang menormalkan profitabilitas.

Kesimpulan

Bundling adalah langkah terakhir dalam pipeline MEV — mengubah peluang terdeteksi menjadi keuntungan aktual. Deteksi konflik memastikan bundle konsisten, strategi bidding kompetitif memastikan inklusi, dan monitoring memberikan feedback untuk iterasi. Keseluruhan seri Deep EVM dari artikel 1 hingga 16 telah membangun fondasi lengkap: dari opcode EVM, melalui Yul dan Huff, hingga arsitektur bot MEV produksi.