Tekan ESC untuk menutup

Profit Bot MEV & Biaya Gas: Panduan Arbitrase & Strategi

Ekonomi murni dari MEV bermuara pada persaingan ketat memperebutkan blok transaksi, di mana jeda jaringan sekecil milidetik saja bisa melumat seluruh potensi cuan Anda. Menjalankan bot sendiri di Ethereum atau jaringan L2 EVM sudah lama bukan lagi cara mudah untuk cari duit. Pasar ini sekarang dikuasai oleh para pencari (searcher) spesialis yang menyewa server di pusat data Frankfurt dan Tokyo tepat di sebelah node validator.

Angka Riil dan Profitabilitas

Bot mandiri yang dijalankan dari server rumahan atau VPS cloud biasa hampir 95% bakal berdarah-darah alias rugi akibat lelang gas. Profitabilitas sangat bergantung pada strategi yang dipakai:

  • Arbitrase Atom (Atomic Arbitrage): Margin profit per transaksi telah menyusut hingga pecahan persen. Cuan bersih harian dari bot yang sukses berkisar antara $100 hingga $3.000 selama periode volatilitas tinggi. Risiko kehilangan modal nol besar karena seluruh transaksi dibungkus dalam satu smart contract atomik: jika kondisi meleset, seluruh rangkaian transaksi akan di-revert otomatis.
  • Serangan Sandwich (Sandwich Attacks): Potensi cuannya lebih tinggi, bisa meraup $500 hingga $10.000 per hari pada pair likuiditas rendah di Uniswap v2 atau AMM serupa. Namun praktiknya jauh lebih brutal. Bot-bot kompetitor saling antre lewat private transaction pool, jor-joran menaikkan suap ke validator untuk menyalip yang lain.
  • Likuidasi (Liquidations): Pasar spot protokol peminjaman seperti Aave memang mendatangkan cuan jumbo, tetapi butuh modal jutaan dolar untuk menutup utang dan melunasi posisi secara instan. Pemain solo minggir dulu.

Struktur Biaya Gas dan Cara Kerja Lewat Builder

Pengeluaran terbesar saat menjalankan bot MEV bukanlah transaksi yang berhasil, melainkan percobaan yang gagal dan lelang prioritas gas (Gas Priority Auction).

  • Public Mempool: Mengirim transaksi tanpa melewati private relay dijamin bikin boncos. Bot amatiran mendeteksi transaksi korban, lalu mengirim transaksinya sendiri dengan gas lebih tinggi, tapi bot saingan keburu menyusot lewat RPC privat. Akhirnya, transaksi Anda tereksekusi di harga terburuk atau malah gagal total (revert), membakar gas asli di blockchain.
  • Block Builder dan Flashbots: Arbitrase modern bergantung penuh pada eth_sendBundle. Anda merangkai beberapa transaksi menjadi satu bundle dan mengirimkannya langsung ke block builder (Beaverbuild, Titan, Flashbots).
  • Biaya Kegagalan: Kelebihan private bundle adalah ketika arbitrase gagal, transaksi tersebut sama sekali tidak masuk ke dalam blok. Anda tidak perlu bayar biaya jaringan untuk tembakan yang meleset. Kekurangannya, validator menggondol sebagian besar keuntungan sebagai suap langsung (coinbase.transfer), dan hanya menyisakan 5% hingga 15% dari kotoran profit untuk developer.

Tabel Metrik Strategi MEV

StrategiModal AwalRata-rata Cuan Bersih HarianTingkat KeberhasilanPenyebab Utama Rugi
Arbitrase Atomdari $5.000$50 - $50015-25%Kalah cepat dari latensi jaringan kompetitor
Serangan Sandwichdari $20.000$200 - $3.0005-10%Kecolongan biaya gas tinggi di lelang validator
Likuidasidari $100.000+$1.000 - $10.000+< 2%Kekurangan modal untuk melunasi pinjaman jumbo

Contoh Pengiriman Bundle Privat dengan Python

Berikut adalah kerangka skrip Python fungsional menggunakan pustaka web3.py untuk mengirim bundle melalui penyedia yang kompatibel dengan Flashbots. Kode sudah dibersihkan dari berbagai abstraksi yang tidak perlu.

import os
from eth_account import Account
from eth_account.signers.local import LocalAccount
from web3 import Web3
from flashbots import flashbot
# Kunci untuk menandatangani permintaan relay (reputasi di Flashbots).
# JANGAN gunakan kunci yang menyimpan dana asli Anda.
signature_account: LocalAccount = Account.from_key(os.environ["FLASHBOTS_SIGNER_KEY"])
# Kunci privat pengirim transaksi
sender: LocalAccount = Account.from_key(os.environ["SENDER_PRIVATE_KEY"])
w3 = Web3(Web3.HTTPProvider(os.environ["ETH_NODE_URL"]))
flashbot(w3, signature_account, "https://relay-sepolia.flashbots.net")
def build_signed_tx(nonce: int) -> bytes:
    base_fee = w3.eth.get_block("latest")["baseFeePerGas"]
    tx = {
        "to": sender.address,          # contoh: transfer ke diri sendiri
        "value": 0,
        "gas": 21_000,
        "maxFeePerGas": base_fee * 2 + Web3.to_wei(2, "gwei"),
        "maxPriorityFeePerGas": Web3.to_wei(2, "gwei"),
        "nonce": nonce,
        "chainId": w3.eth.chain_id,
        "type": 2,
    }
    return sender.sign_transaction(tx).rawTransaction  # pada versi baru: .raw_transaction
def send_private_bundle(target_block: int):
    nonce = w3.eth.get_transaction_count(sender.address)
    bundle = [{"signed_transaction": build_signed_tx(nonce)}]
    # Simulasi sebelum dikirim
    w3.flashbots.simulate(bundle, target_block)
    result = w3.flashbots.send_bundle(bundle, target_block_number=target_block)
    result.wait()  # menunggu hingga blok target_block diproses
    try:
        return result.receipts()
    except Exception:
        return None  # bundle tidak masuk blok: ulangi di blok berikutnya
if __name__ == "__main__":
    target = w3.eth.block_number + 1
    receipts = send_private_bundle(target)
    print("Masuk ke dalam blok" if receipts else "Bundle tidak masuk, coba lagi di blok berikutnya")

Bundle hanya berlaku untuk satu target blok saja, jadi dalam praktiknya pengiriman harus dilakukan berulang-ulang secara looping untuk beberapa blok berturut-turut. Gagal masuk blok bukanlah error: persaingan murni ditentukan oleh besaran tip yang Anda berikan ke builder.

Profitabilitas bot mandiri sangat bergantung pada biaya infrastruktur. Menyewa server dedicated di rak yang sama dengan validator di pusat data bisa menelan biaya mulai dari $500 per bulan. Tanpa keunggulan perangkat keras semacam itu, bot Anda secara fisik tidak akan sempat menghitung status pool mendahului para rival. Siapa yang kabel jaringannya paling pendek ke validator dan algoritmanya paling gesit, dialah yang menang.

Flash loan memungkinkan kita menjalankan operasi arbitrase skala besar tanpa modal jumbo sendiri, memanfaatkan pinjaman tanpa jaminan (unsecured borrowing) dalam satu transaksi tunggal dengan mekanisme rollback otomatis jika terjadi kerugian.

Flash Loan dan Arsitektur Smart Contract

Punya modal ratusan ribu dolar buat main arbitrase jelas bukan keharusan lagi. Kontrak integrasi dengan pool Aave v3 atau Balancer memungkinkan kita narik flash loan tanpa agunan dalam batasan satu transaksi. Bot minjam aset, muterin lewat pair DEX, balikin pinjaman plus fee 0.09%, dan nyimpen sisanya ke saldo creator. Kalau kalkulasi akhirnya boncos, seluruh transaksi otomatis ke-revert dan kita cuma rugi biaya gas buat manggil fungsi tersebut.

Nulis kontrak arbitrase pakai Solidity butuh optimasi tingkat dewa buat bytecode EVM. Pakai interface standar ERC-20 lewat SafeERC20 cuma bakal nambahin cek redordan yang ngabisin gas berharga pas validasi batas transaksi. Dev berpengalaman biasanya milih manggil fungsi low-level langsung pakai call, biar operasi baca-tulis memory permanen (SLOAD/SSTORE) bisa ditekan seminim mungkin.

Contoh Template Solidity

Berikut adalah template flash loan Aave V3 buat pool Uniswap V2, bersih tanpa library pihak ketiga yang bloated:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
}
/// Aave V3: flash loan satu aset
interface IPool {
    function flashLoanSimple(
        address receiverAddress,
        address asset,
        uint256 amount,
        bytes calldata params,
        uint16 referralCode
    ) external;
}
interface IUniswapV2Pair {
    function token0() external view returns (address);
    function getReserves() external view returns (uint112, uint112, uint32);
    function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
}
/// Arbitrase flash loan Aave V3: asset -> tokenB (pair1) -> asset (pair2).
/// Contoh untuk pool tipe Uniswap V2. Belum diaudit.
contract FlashArbitrage {
    error Unauthorized();
    error InvalidCaller();
    error InvalidInitiator();
    error TransferFailed();
    error ApproveFailed();
    error InsufficientProfit(uint256 balanceAfter, uint256 required);
    address private immutable OWNER;
    IPool private immutable POOL;
    constructor(address aavePool) {
        OWNER = msg.sender;
        POOL = IPool(aavePool); // ambil alamat Pool dari PoolAddressesProvider jaringan terkait
    }
    modifier onlyOwner() {
        if (msg.sender != OWNER) revert Unauthorized();
        _;
    }
    /// Entry point. Pinjam `amount` dari token `asset` dan trigger looping di executeOperation.
    function executeArbitrage(
        address asset,
        uint256 amount,
        address tokenB,
        address pair1,
        address pair2,
        uint256 minProfit
    ) external onlyOwner {
        bytes memory params = abi.encode(tokenB, pair1, pair2, minProfit);
        POOL.flashLoanSimple(address(this), asset, amount, params, 0);
    }
    /// Callback Aave V3. Dipanggil oleh pool setelah pinjaman dicairkan.
    function executeOperation(
        address asset,
        uint256 amount,
        uint256 premium,
        address initiator,
        bytes calldata params
    ) external returns (bool) {
        // 1. Callback cuma boleh dipanggil pool Aave...
        if (msg.sender != address(POOL)) revert InvalidCaller();
        // 2. ...dan cuma atas permintaan kontrak ini sendiri
        if (initiator != address(this)) revert InvalidInitiator();
        (address tokenB, address pair1, address pair2, uint256 minProfit) =
            abi.decode(params, (address, address, address, uint256));
        // Saldo sudah termasuk dana pinjaman
        uint256 balanceBefore = IERC20(asset).balanceOf(address(this));
        uint256 amountB = _swap(pair1, asset, amount);
        _swap(pair2, tokenB, amountB);
        // Profit = balanceAfter - balanceBefore - premium (fee pinjaman)
        uint256 balanceAfter = IERC20(asset).balanceOf(address(this));
        uint256 required = balanceBefore + premium + minProfit;
        if (balanceAfter < required) revert InsufficientProfit(balanceAfter, required);
        // Aave narik utang sendiri via transferFrom, jadi butuh approve
        _safeApprove(asset, address(POOL), amount + premium);
        return true;
    }
    function withdraw(address token, uint256 amount) external onlyOwner {
        _safeTransfer(token, OWNER, amount);
    }
    function _swap(address pair, address tokenIn, uint256 amountIn) private returns (uint256 amountOut) {
        (uint256 r0, uint256 r1, ) = IUniswapV2Pair(pair).getReserves();
        bool zeroForOne = tokenIn == IUniswapV2Pair(pair).token0();
        (uint256 reserveIn, uint256 reserveOut) = zeroForOne ? (r0, r1) : (r1, r0);
        // Rumus Uniswap V2 (fee 0,3%)
        uint256 amountInWithFee = amountIn * 997;
        amountOut = (amountInWithFee * reserveOut) / (reserveIn * 1000 + amountInWithFee);
        _safeTransfer(tokenIn, pair, amountIn);
        IUniswapV2Pair(pair).swap(
            zeroForOne ? 0 : amountOut,
            zeroForOne ? amountOut : 0,
            address(this),
            "" // data kosong: ini swap biasa, bukan flash swap
        );
    }
    function _safeTransfer(address token, address to, uint256 amount) private {
        if (token.code.length == 0) revert TransferFailed();
        (bool ok, bytes memory data) = token.call(abi.encodeCall(IERC20.transfer, (to, amount)));
        if (!ok || (data.length != 0 && !abi.decode(data, (bool)))) revert TransferFailed();
    }
    function _safeApprove(address token, address spender, uint256 amount) private {
        if (token.code.length == 0) revert ApproveFailed();
        (bool ok, bytes memory data) = token.call(abi.encodeCall(IERC20.approve, (spender, amount)));
        if (!ok || (data.length != 0 && !abi.decode(data, (bool)))) revert ApproveFailed();
    }
}

Jalan Buntu Infrastruktur AWS

Ngeladenin bot searcher pakai cloud VPS kayak Amazon Web Services atau Google Cloud mah cuma bakal bikin anggaran ludes sia-sia. Virtualisasi nambahin latensi jitter ke network stack, plus jalur koneksi bersama gampang banget ngalamin packet loss pas mempool lagi padat-padatnya.

Setup yang kompetitif wajib pakai server fisik bare-metal dengan clock speed CPU single-core tinggi, storage NVMe ngebut buat node lokal Geth atau Reth, dan jalur dedicated gigabit langsung ke datacenter Frankfurt. Jalanin lightweight node sendiri itu harga mati, soalnya penyedia RPC publik macam Infura atau Alchemy sengaja nge-throttle kecepatan deliver blok baru dan nunda notifikasi pending transaction nyampe 100-300 milidetik yang sifatnya krusial.

Cuan di MEV itu bukan dikuasai yang model matematiknya paling rumit, tapi siapa yang fisiknya paling dekat ke validator dan jago ngitung efisiensi gas sampai level instruksi assembly terkecil di bytecode.

Rangkum postingan blog ini dengan:

FAQ

Keuntungan bersih bot MEV mandiri berkisar antara $50 hingga $500 per hari untuk strategi arbitrase atomik antar-DEX, serta $200 hingga $3.000 per hari untuk serangan sandwich pada periode volatilitas tinggi. Sebagian besar estimasi pendapatan kotor tergerus oleh penawaran prioritas builder blok, sehingga infrastruktur tanpa kolokasi server ke node validator sering mengalami kerugian akibat kekalahan jeda waktu (latency).

Struktur biaya gas bot MEV terdiri dari opcat eksekusi dasar jaringan serta biaya prioritas validator (priority fee) yang dikirim melalui relay privat builder seperti Flashbots menggunakan instrumen eth_sendBundle. Metode pengiriman privat mencegah terbuangnya gas saat transaksi gagal, namun pengembang harus menyerahkan 85% hingga 95% dari total profit transaksi langsung ke validator melalui fungsi coinbase.transfer agar bundle berhasil dimasukkan ke dalam blok.

Pembuatan bot sandwich attack secara independen di jaringan utama EVM tidak lagi menguntungkan akibat ketertinggalan latensi jaringan, tingginya kebutuhan modal ликвидность, serta dominasi mempool privat. Tanpa akses ke dedicated node bare-metal berkecepatan di bawah satu milidetik, pengembang independen terpaksa membayar biaya prioritas berlebih pada lelang builder yang menghabiskan seluruh marjin keuntungan dari eksekusi alur transaksi swap.
Astra EXMON

Astra is the official voice of EXMON and the editorial collective dedicated to bringing you the most timely and accurate information from the crypto market. Astra represents the combined expertise of our internal analysts, product managers, and blockchain engineers.

...

Sampaikan pemikiran Anda

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *