MEV dan Sandwich Attack: Simulasi AMM yang Konsisten
Simulasi sandwich attack dengan arah reserve, output korban, dan profit attacker yang dihitung dari arus aset sebenarnya.
0xNN · · 8 min read
MEV dan Sandwich Attack: Simulasi AMM yang Konsisten
Maximal Extractable Value (MEV) adalah nilai tambahan yang dapat diperoleh dari produksi blok melalui pemilihan, pengecualian, atau perubahan urutan transaksi. Setelah Ethereum beralih ke proof-of-stake, istilah “maximal” menggantikan “miner” karena validator dan block builder berperan dalam proses tersebut.
Definisi dan contoh resminya dapat dibaca di dokumentasi MEV ethereum.org.
Artikel ini membahas sandwich attack dari sisi mekanisme dan kode. Ini bukan panduan menjalankan bot atau rekomendasi transaksi aset.
Searcher, builder, dan validator
Penjelasan “bot membayar gas lebih tinggi lalu miner memasukkannya lebih dahulu” terlalu sederhana untuk Ethereum modern.
Secara konseptual:
• Searcher mendeteksi peluang arbitrase, likuidasi, atau ordering.
• Builder menyusun kandidat blok dan memilih urutan transaksi/bundle.
• Validator mengusulkan blok.
• Relay dan mekanisme seperti MEV-Boost dapat menjadi bagian dari alur block building.
Detailnya dapat berubah mengikuti infrastruktur jaringan. Hal yang penting bagi pengguna DEX: transaksi yang terlihat sebelum inclusion dapat memengaruhi strategi pihak lain.
Cara sandwich terjadi
Misalkan korban akan membeli ETH dengan USDC pada AMM.
1. Attacker membeli ETH sebelum korban.
2. Harga ETH di pool bergerak naik.
3. Transaksi korban membeli ETH pada kondisi yang lebih buruk.
4. Attacker menjual ETH setelah transaksi korban.
Strategi ini hanya menguntungkan jika hasil penjualan attacker lebih besar daripada modal, fee AMM, biaya inclusion, dan risiko transaksi gagal atau dikalahkan searcher lain.
Simulator constant product
Kita gunakan rumus output dengan fee 0,3%:
def get_amount_out(amount_in, reserve_in, reserve_out):
amount_in_with_fee = amount_in * 997
return (
amount_in_with_fee * reserve_out
/ (reserve_in * 1000 + amount_in_with_fee)
)
Pool awal:
1.000 ETH
2.000.000 USDC
Spot price: 2.000 USDC/ETH
Simulasi:
reserve_eth = 1_000.0
reserve_usdc = 2_000_000.0
1. Attacker front-run: masukkan 20.000 USDC, ambil ETH.
attacker_usdc_in = 20_000.0
attacker_eth = get_amount_out(
attacker_usdc_in,
reserve_usdc,
reserve_eth,
)
reserve_usdc += attacker_usdc_in
reserve_eth -= attacker_eth
2. Korban: masukkan 100.000 USDC setelah harga bergerak.
victim_usdc_in = 100_000.0
victim_eth = get_amount_out(
victim_usdc_in,
reserve_usdc,
reserve_eth,
)
reserve_usdc += victim_usdc_in
reserve_eth -= victim_eth
3. Attacker back-run: jual seluruh ETH yang didapat.
attacker_usdc_out = get_amount_out(
attacker_eth,
reserve_eth,
reserve_usdc,
)
reserve_eth += attacker_eth
reserve_usdc -= attacker_usdc_out
gross_profit = attacker_usdc_out - attacker_usdc_in
print(f"ETH attacker : {attacker_eth:.6f}")
print(f"ETH korban : {victim_eth:.6f}")
print(f"Profit kotor : {gross_profit:.2f} USDC")
Output:
ETH attacker : 9.871580
ETH korban : 46.570648
Profit kotor : 1884.80 USDC
“Profit kotor” belum mengurangi biaya transaksi, pembayaran kepada builder/validator, kegagalan bundle, dan kompetisi.
Membandingkan hasil korban
Tanpa transaksi attacker:
victim_without_attack = get_amount_out(
100_000,
2_000_000,
1_000,
)
loss_in_eth = victim_without_attack - victim_eth
print(f"Tanpa attack : {victim_without_attack:.6f} ETH")
print(f"Selisih : {loss_in_eth:.6f} ETH")
Output:
Tanpa attack : 47.482974 ETH
Selisih : 0.912325 ETH
Simulasi ini menunjukkan dampak ordering dengan reserve yang konsisten. Ia belum merepresentasikan seluruh detail on-chain seperti gas, base fee, builder bid, slippage check, revert, token decimals, dan transaksi lain pada blok yang sama.
Slippage tolerance adalah batas, bukan pelindung sempurna
Pada swap, pengguna biasanya menentukan amountOutMin. Jika output aktual lebih kecil, transaksi revert.
Slippage tolerance yang sangat longgar memberi ruang execution yang lebih buruk. Namun sekadar memilih angka serendah mungkin juga bukan solusi universal: transaksi dapat gagal ketika harga bergerak secara wajar atau likuiditas berubah.
Pendekatan yang lebih masuk akal:
• periksa price impact;
• gunakan minimum output yang sesuai;
• pecah transaksi jika masuk akal;
• bandingkan likuiditas/rute;
• gunakan mekanisme private order flow atau MEV protection yang benar-benar didukung wallet/aggregator;
• pahami trust assumption layanan tersebut.
Flashbots Protect
Flashbots Protect menawarkan jalur transaksi yang dirancang untuk melindungi pengguna dari frontrunning dan dapat membagikan sebagian backrunning MEV melalui MEV-Share.
Namun “private” tidak berarti bebas risiko atau dijamin selalu masuk blok. Sebelum memakai RPC atau layanan proteksi:
• baca dokumentasi jaringan yang didukung;
• periksa kebijakan transaksi gagal;
• pahami pihak yang menerima transaksi;
• jangan menganggap semua wallet otomatis memakai private order flow;
• uji dengan nominal kecil.
MEV tidak selalu berarti serangan
MEV juga mencakup arbitrase yang menyamakan harga antar-DEX dan likuidasi yang menjaga protokol pinjaman tetap solvent. Dampaknya bergantung pada jenis aktivitas.
Sandwich trading merugikan pengguna karena memberikan execution lebih buruk. Arbitrase dan likuidasi dapat memiliki fungsi ekonomi bagi protokol, walaupun tetap menimbulkan kompetisi dan potensi sentralisasi.
Kesalahan umum ketika menjelaskan MEV
Menghitung perubahan reserve sebagai profit bot.
Profit harus dihitung dari aset yang benar-benar masuk dan keluar dari wallet attacker, setelah seluruh biaya.
Membalik arah reserve.
Jika trader memasukkan USDC untuk membeli ETH, reserve USDC naik dan reserve ETH turun.
Menganggap gas tinggi menjamin aman.
Ordering tidak hanya ditentukan oleh satu angka gas; builder, bundle, private flow, dan transaksi lain ikut berpengaruh.
Menganggap chain tertentu “MEV-resistant”.
Desain mempool dan block production dapat mengubah bentuk MEV, bukan otomatis menghilangkannya.
Ringkasan
MEV muncul karena ordering transaksi memiliki nilai ekonomi. Pada sandwich attack, attacker membeli sebelum korban dan menjual setelah korban. Simulator harus menjaga arah reserve, menghitung output AMM dengan fee, dan menghitung profit dari arus aset attacker—bukan dari selisih balance pool.
Untuk memahami konsep, gunakan simulator. Untuk menilai risiko transaksi nyata, periksa implementasi DEX, wallet, RPC, builder flow, dan kondisi jaringan yang digunakan.
Referensi
• Ethereum.org: Maximal Extractable Value
• Flashbots documentation
• Uniswap v2 Core whitepaper
• Uniswap v2 Pair contract