687 bacaan
687 bacaan

Dalam Hutan Gelap: Teknik Kerja DeFi Arbitrase

oleh Simone Convertini45m2025/05/31
Read on Terminal Reader

Terlalu panjang; Untuk membaca

Cara membangun robot arbitrase DeFi yang bekerja memanfaatkan perbedaan harga di seluruh AMM.
featured image - Dalam Hutan Gelap: Teknik Kerja DeFi Arbitrase
Simone Convertini HackerNoon profile picture

1. pengenalan –ke dalam hutan gelap

1. pengenalan –

Pada suatu malam, Dan Robinson, seorang peneliti di perusahaan investasi Paradigm, melihat panggilan darurat di saluran Uniswap Discord.Duapengguna lain, tetapi untuk kontrak Uniswap itu sendiri, di mana mereka tampak hilang secara tak tergantikan.

Robinson, bagaimanapun, melihat kilat harapan. dia menyadari bahwa siapa pun dapat memicuburnfungsi pada kontrak, perintah publik yang akan memaksa kontrak untuk melepaskan token yang terjebak ke orang yang memanggilnya.

Mengakui kesempatan untuk menjadi pahlawan dengan topi putih, Robinson mempersiapkan transaksi penyelamatan. tetapi dia tahu dia tidak sendirian. mempool Ethereum - ruang tunggu publik untuk transaksi yang sedang berlangsung - adalah tempat berburu bot canggih yang dikenal sebagai "frontrunners umum." para predator ini terus-menerus memindai untuk tindakan yang menguntungkan, langsung menyalinnya, dan menggantikan alamat asli dengan mereka sendiri untuk mencuri hadiah.

Untuk melampaui mereka, Robinson merancang transaksi dua bagian yang cerdas, berharap untuk mendapatkan kedua bagian dieksploitasi secara bersamaan, tidak meninggalkan jendela untuk penculikan. Ini tidak berhasil. Pada saat transaksi pertamanya muncul, sebuah bot mendeteksi itu, mereplikasi seluruh strategi, dan merampok $ 12.000 sebelum transaksi kedua Robinson bahkan dapat dikonfirmasi.

Dalam sebuah esai yang sekarang terkenal tentang insiden ini, Robinson memberi nama ekosistem yang bermusuhan dan tak terlihat ini.Ethereum is a Dark Forest.

Dalam artikel ini, kita akan menyelidiki desain sistem yang mampu membaca operasi real-time dan data dari transaksi blockchain, dengan tujuan melakukan arbitrase.mathematical models underlying AMM pricingMaka, masuklah ke dalamalgorithms for opportunity detection and optimal price entryDefinisi dariarchitectural componentsdari bot kami, dan mendiskusikancritical strategiesdiperlukan untuk berhasil dan aman melaksanakan arbitrase dalam lingkungan taruhan tinggi ini.


Landscape DeFi: AMM, Liquidity, dan Peluang Arbitrase

The “Dark Forest” yang dijelaskan dalam pengantar kami bukan hanya lingkungan yang bermusuhan; itu adalah ekosistem yang dinamis yang dibangun pada paradigma keuangan baru: Decentralized Finance (DeFi). Di inti, DeFi bertujuan untuk mereproduksi layanan keuangan tradisional di jaringan blockchain, menghilangkan kebutuhan untuk perantara melalui penggunaan kontrak cerdas yang mengeksekusi sendiri.

Pembuat Pasar Otomatis (AMMs): tulang belakang pertukaran terdesentralisasi

Pertukaran tradisional bergantung pada buku pesanan, di mana pembeli dan penjual menempatkan penawaran dan permintaan, dan mesin matching sentral memfasilitasi perdagangan. DeFi memperkenalkan model yang sangat berbeda: Pembuat Pasar Otomatis (AMM). Alih-alih mencocokkan pembeli dan penjual secara langsung, AMM memanfaatkan pool likuiditas - kontrak cerdas yang memegang cadangan dua atau lebih token - untuk memfasilitasi perdagangan. Pengguna, yang dikenal sebagai penyedia likuiditas (LPs), menyetorkan nilai setara dari pasangan token ke dalam pool ini, menghasilkan bagian dari biaya perdagangan sebagai imbalan.

Harga aset dalam pool AMM ditentukan secara algoritmik oleh aconstant product formulaDikutip dari Uniswap:

Di sini, x dan y mewakili jumlah dari dua token dalam pool likuiditas, dan k adalah konstan. Ketika seorang pengguna berdagang satu token untuk yang lain, jumlah x dan y dalam pool berubah, tetapi produk mereka k harus tetap konstan. Mekanisme ini secara dinamis menyesuaikan harga: membeli lebih banyak token A akan mengurangi jumlahnya di pool, sehingga meningkatkan harga dibandingkan token B, dan sebaliknya. Hubungan antara cadangan dan harga ini menciptakanbonding curve, yang mendikte poin harga yang tersedia untuk perdagangan.

Dari model ini, adalah mungkin untuk menghitung secara deterministis jumlah output (dy) dari swap, mengingat jumlah input (dx) dan cadangan pra-swap dari dua token (x dan y):

Key characteristics of AMMs:

  • Always-on Liquidity: Tidak seperti buku pesanan yang bisa menjadi tipis, AMM selalu menawarkan likuiditas selama ada token di kolam.
  • Tanpa izin: Siapa pun dapat menjadi penyedia likuiditas atau perdagangan pada AMM tanpa memerlukan persetujuan.
  • Penemuan Harga: Harga ditentukan oleh rasio aset dalam kolam, menyesuaikan dengan setiap perdagangan.
  • Slippage: Perdagangan besar dapat secara signifikan memindahkan harga di dalam kolam, menyebabkan fenomena yang dikenal sebagai slippage, di mana harga yang dijalankan lebih buruk dari harga yang dinyatakan.

Sementara model x⋅y=k (sering disebut sebagai Uniswap V2) meletakkan dasar, AMM telah berevolusi. Uniswap V3, misalnya, memperkenalkan “konsentrasi likuiditas” (CLAMM), memungkinkan LP untuk mendistribusikan modal mereka dalam kisaran harga tertentu. Ini secara signifikan meningkatkan efisiensi modal tetapi juga meningkatkan kompleksitas untuk LP dan, akibatnya, untuk arbitrator yang perlu melacak likuiditas di berbagai kisaran.we will primarily focus on AMMsmenggunakan rumus produk konstan (seperti kolam gaya Uniswap V2), karena mereka memberikan pemahaman dasar sebelum menangani model yang lebih kompleks.

The Essence of Arbitrage in DeFi

Arbitrase, dalam bentuknya yang paling murni, adalah pembelian dan penjualan simultan aset di pasar yang berbeda untuk keuntungan dari perbedaan harga. Dalam DeFi, ini diterjemahkan ke dalam memanfaatkan perbedaan harga antara pool AMM yang berbeda, atau antara AMM dan Exchange Centralized (CEX), untuk pasangan token yang sama. sifat yang tidak diperbolehkan dari DeFi dan likuiditas yang terfragmentasi di berbagai protokol menciptakan lahan yang subur untuk peluang-peluang ini. Volatilitas tinggi dan kurangnya regulasi di ruang keuangan yang muncul ini sering menyebabkan penyimpangan harga yang signifikan, yang merupakan sumber hidup dari arbitrase.

Jenis-jenis Peluang Arbitrase di DeFi

  • Sebagai contoh, jika 1 ETH berdagang untuk 2000 DAI pada Uniswap A, tetapi 1 ETH berdagang untuk 2010 DAI pada Uniswap B, seorang arbitrageur dapat membeli ETH pada Uniswap A dengan DAI, dan segera menjual ETH itu untuk DAI pada Uniswap B, mengisi 10 DAI perbedaan (dengan mengurangi biaya gas dan slippage).
  • Triangular Arbitration (Multi-Leg): Jenis arbitrase ini melibatkan tiga atau lebih aset dalam pertukaran yang sama (atau melalui beberapa pertukaran) untuk membentuk siklus yang menguntungkan. Sebagai contoh, seorang arbitrager mungkin mulai dengan Token A, menukarnya untuk Token B, kemudian Token B untuk Token C, dan akhirnya Token C kembali ke Token A, berakhir dengan lebih banyak Token A daripada yang dimulai dengan. Contoh umum tentang Uniswap mungkin: WETH -> DAI -> USDC -> WETH. Tujuan utama kami adalah untuk menerapkan dan mengoperasikan arbitrase Multi-Leg antara DEX AMM yang berbeda.
  • Flash Loan Arbitration: Aspek yang kuat dan unik dari DeFi, pinjaman flash memungkinkan pengguna untuk meminjamkan aset yang tidak terikat, menggunakannya untuk serangkaian transaksi (seperti arbitrase), dan membayar kembali pinjaman - semua dalam satu transaksi blockchain. Jika seluruh urutan operasi (meminjam, perdagangan, pembayaran) tidak dapat diselesaikan dengan sukses dalam transaksi tunggal itu, seluruh transaksi dikembalikan, seolah-olah tidak pernah terjadi. Ini menghilangkan kebutuhan untuk modal awal yang signifikan dan secara signifikan menurunkan hambatan masuk untuk arbitrase skala besar, tetapi juga berarti seluruh strategi arbitrase harus hati-hati disusun dalam satu operasi atom. Kami akan menggabungkan opsi pinjaman flash ke bot kami, khususnya untuk situasi di mana jumlah arbitrase yang diperlukan sangat tinggi, memungkinkan kami untuk melakukan perdagangan jauh melebihi modal awal kami.

Lomba untuk keuntungan: tantangan dan persaingan

Pemandangan DeFi adalah pasar yang sangat efisien. ketidakseimbangan harga melambat, seringkali ada hanya selama milisekunder sebelum dieksploitasi oleh bot canggih. persaingan yang intens ini menyajikan beberapa tantangan penting bagi setiap arbitrageur yang bercita-cita:

  • Gas Fees: Every interaction with a smart contract incurs a transaction fee (gas), which can vary significantly based on network congestion. A profitable arbitrage opportunity must yield enough profit to cover these costs.

  • Slippage: The larger the trade relative to the pool’s liquidity, the greater the slippage, eroding potential profits. Accurately modeling slippage is crucial for calculating true profitability.

  • Latency: The speed at which an arbitrage bot can detect an opportunity, calculate the optimal trade, construct a transaction, and submit it to the network is paramount. Even milliseconds can make the difference between profit and loss.

  • Frontrunning and MEV: As discussed in the introduction, the “Dark Forest” is dominated by generalized frontrunners. These bots actively monitor the mempool for pending profitable transactions, replicate them, and submit their own transaction with a higher gas price to ensure their transaction is included in a block before the original one. This phenomenon falls under the umbrella of Maximal Extractable Value (MEV), representing the total value that can be extracted from block production in excess of the standard block reward and gas fees by arbitraging, liquidating, or reordering transactions within a block. Successfully navigating this environment often requires advanced strategies like leveraging MEV-Boost relays or private transaction pools. To mitigate the risk of being intercepted in public mempools, our implementation will primarily operate on Base, an EVM-compatible Layer 2 (L2) blockchain. Base’s architecture, which currently does not expose a public mempool in the same manner as Ethereum’s Layer 1, offers a different environment for transaction submission, potentially reducing traditional frontrunning risks.

  • Complexity of AMMs: As AMMs evolve (e.g., Uniswap V3’s concentrated liquidity), the mathematical modeling and state tracking required for accurate arbitrage calculations become significantly more complex.

    Understanding these foundational elements of DeFi, from the mechanics of AMMs to the cut-throat nature of arbitrage competition, sets the stage for designing a robust and effective arbitrage bot. In the next chapter, we will begin to lay out the architectural blueprint for such a system.

Desain Arsitektur: Membangun Infrastruktur Arbitrase Bot

Membangun robot arbitrase yang menguntungkan di DeFi’s “Dark Forest” membutuhkan arsitektur yang memprioritaskan kecepatan, keandalan, dan presisi. Setiap milisekund bergantung, dan kemampuan untuk memproses data real-time, mengidentifikasi peluang, dan mengeksekusi perdagangan dengan cepat sangat penting.

Go dipilih sebagai bahasa pengembangan utama karena kinerja yang luar biasa, primitif concurrency yang kuat (goroutine dan saluran), dan ekosistem yang kuat untuk pemrograman jaringan dan interaksi sistem tingkat rendah. Fitur-fitur ini sangat penting untuk menangani aliran data blockchain yang tinggi dan kebutuhan untuk pemrosesan paralel dalam sistem arbitrase real-time.go-ethereumSalah satunya adalah Ethereum client.

Arsitektur bot dibangun sebagaievent-driven systemterdiri dari beberapa layanan independen (modul), masing-masing berjalan dalam proses paralel (goroutines). Layanan ini berkomunikasi secara asynchronous dengan mengirim pesan melalui saluran Go, memastikan desain yang mudah dihubungkan dan sangat responsif. pendekatan ini memungkinkan penggunaan sumber daya yang efisien, menyederhanakan isolasi kesalahan, dan memungkinkan skala yang lancar dari komponen individual.

Arsitektur sistem secara keseluruhan

Infrastruktur bot arbitrase dapat dipvisualisasikan sebagai pipa, di mana data mengalir dari blockchain, diproses dan dianalisis, dan berpuncak dalam pelaksanaan perdagangan yang menguntungkan.

  • Blockchain Data Reader Service: Responsible for real-time ingestion of blockchain events data.

  • Market Graph Service: Maintains an in-memory representation of the DeFi market and identifies arbitrage paths.

  • Arbitrage Strategy Service: Evaluates detected opportunities for profitability and prepares trade instructions.

  • Transaction Builder Service: Constructs and dispatches blockchain transactions.

  • Honeywall Service: A post-execution checker that enhances security and maintains market integrity by identifying and blacklisting malicious pools.

    This modularity allows each service to focus on a specific task, minimizing dependencies and optimizing performance for its particular workload. Communication between services is strictly asynchronous, leveraging Go’s channels for message passing, which naturally facilitates a non-blocking and highly concurrent operation.

Layanan Pembaca Data Blockchain: Mata dan Telinga Bot kami dalam Aliran Data

Layanan ini bertindak sebagai antarmuka utama bot dengan data mentah, real-time yang mengalir melalui blockchain. di “Dark Forest”, informasi adalah mata uang, dan kemampuan kami untuk cepat dan akurat menelan itu adalah yang utama.extract crucial financial data pointsyang akan memberi makan mesin pengambilan keputusan arbitrase kami.

  • Koneksi dan Pengambilan Data: Pembaca terhubung ke node blockchain melalui WebSockets. Koneksi persisten, dua arah ini memungkinkan penerimaan langsung headers blok baru dan, yang lebih penting, log peristiwa yang dikeluarkan oleh kontrak cerdas. Layanan ini dikonfigurasi untuk secara khusus mendengarkan peristiwa Swap, Mint, Burn, dan Sync dari kontrak cerdas Decentralized Exchange (DEX). peristiwa-peristiwa ini sangat penting karena mereka menunjukkan perubahan dalam cadangan pool likuiditas, secara langsung mempengaruhi harga token.
  • New Block Headers: Dengan berlangganan headers blok baru, kita mendapatkan pemberitahuan segera tentang perubahan status. setiap blok baru mewakili snapshot yang dikonfirmasi dari realitas blockchain saat ini, termasuk transaksi baru, saldo yang diperbarui, dan negara pool likuiditas baru. aliran ini menyediakan data dasar untuk pembaruan periodik dari grafik pasar kami dan untuk mengkonfirmasi hasil dari transaksi kami sendiri.
func (er *EthereumReader) SubscribePairs() error {

	parsedABI := constants.PairAbi

	// Set up the filter
	query := ethereum.FilterQuery{
		Topics: [][]common.Hash{
			{
				parsedABI.Events["Swap"].ID,
				parsedABI.Events["Mint"].ID,
				parsedABI.Events["Burn"].ID,
				parsedABI.Events["Sync"].ID,
			},
		},
	}

	logs := make(chan types.Log)

	sub, err := er.ethClient.SubscribeFilterLogs(context.Background(), query, logs)
	if err != nil {
		return err
	}

	// Start Routine to read swaps events
	log.Println("[READING SWAPS...]")
	go func() {
		for {
			select {
			case err = <-sub.Err():
				log.Println("[RESET CONNECTION...] Subscription error: ", err)
				pairInfo := GraphMessage{
					Ok: false,
				}
				*er.pairChan <- pairInfo

				time.Sleep(5 * time.Minute)
				er.ethClient = clients.ResetConnection()
				er.SubscribePairs()

				return
			case vLog := <-logs:
				start := time.Now()

				pairAddress := vLog.Address
				if er.filter.IsPairBlackListed(pairAddress.Hex()) {
					continue
				}

				blockNumber := vLog.BlockNumber
				if blockNumber > er.currentBlockNumber {
					// New block detected, reset cache
					er.lastUpdatedBlock = nil
					er.lastUpdatedBlock = make(map[common.Address]uint64)
					er.currentBlockNumber = blockNumber
				}

				// Check if already updated for this pair in current block
				if _, exists := er.lastUpdatedBlock[pairAddress]; exists {
					continue
				}

				t0, t1, f, r0, r1, err := er.getPairDataFromHelper(pairAddress)
				if err != nil {
					continue
				}

				dex := f.String()
				router, err := constants.GetRouterAddressFromFactory(dex)
				if err != nil {
					continue
				}

				// Update cache
				er.lastUpdatedBlock[pairAddress] = blockNumber
				elapsed := time.Until(start)

				pairInfo := GraphMessage{
					Ok:       true,
					DexCheck: true,
					Pair:     pairAddress.Hex(),
					Token0:   Token{Address: t0.Hex()},
					Token1:   Token{Address: t1.Hex()},
					Reserve0: r0,
					Reserve1: r1,
					Dex:      router,
					GetTime:  elapsed,
				}

				*er.pairChan <- pairInfo
			}
		}
	}()

	return nil
}
  • Custom Smart Contract for Data Aggregation and Pre-filtering: Untuk mengoptimalkan efisiensi dan mengurangi panggilan berlebihan di rantai, Reader menggunakan kontrak pintar kustom, yang ditulis khusus untuk tujuan ini. Kontrak ini berfungsi sebagai agregator, menyediakan panggilan tunggal, dioptimalkan untuk mengambil cadangan dan informasi agregat lainnya untuk beberapa pasangan likuiditas. Fungsi utama dari kontrak kustom ini adalah pre-check yang dibangun untuk fitur penipuan umum atau pajak perdagangan yang berlebihan di dalam kolam sebelum mengembalikan data. Filter awal ini secara signifikan mengurangi risiko berinteraksi dengan kontrak jahat di bawah, bertindak sebagai garis pertama pertahanan terhadap kolam potensial berbahaya atau tidak menguntungkan.
  • Logika inti terletak pada metode checkPair, yang menilai keamanan sepasang token dan mengembalikan data agregat.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract ArbHelperMap {
    mapping(address => address) public factoryToRouter;
    address public owner;
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    constructor() {
        owner = msg.sender;
        // Pre-populate known mappings
        factoryToRouter[0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6] = 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24;
        factoryToRouter[0x02a84c1b3BBD7401a5f7fa98a384EBC70bB5749E] = 0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb;
        factoryToRouter[0xFDa619b6d20975be80A10332cD39b9a4b0FAa8BB] = 0x327Df1E6de05895d2ab08513aaDD9313Fe505d86;
        factoryToRouter[0x71524B4f93c58fcbF659783284E38825f0622859] = 0x6BDED42c6DA8FBf0d2bA55B2fa120C5e0c8D7891;
        factoryToRouter[0x3E84D913803b02A4a7f027165E8cA42C14C0FdE7] = 0x8c1A3cF8f83074169FE5D7aD50B978e1cD6b37c7;
        factoryToRouter[0x9A9A171c69cC811dc6B59bB2f9990E34a22Fc971] = 0x1b7655aa64b7BD54077dE56B64a0f92BCba05b85;
    }
    
    function addFactoryRouter(address factory, address router) external onlyOwner {
        require(factory != address(0) && router != address(0), "Zero address");
        factoryToRouter[factory] = router;
    }
    
    struct Result {
        bool success;
        address token0;
        address token1;
        address factory;
        uint112 reserve0;
        uint112 reserve1;
    }
    
    // Helper function to get pair data
    function _getPairData(address pairAddress) private view returns (
        bool success,
        address token0,
        address token1,
        address factory,
        uint112 reserve0,
        uint112 reserve1,
        address router
    ) {
        success = false;
        
        try IPair(pairAddress).token0() returns (address _token0) {
            token0 = _token0;
            
            try IPair(pairAddress).token1() returns (address _token1) {
                token1 = _token1;
                
                try IPair(pairAddress).factory() returns (address _factory) {
                    factory = _factory;
                    
                    try IPair(pairAddress).getReserves() returns (uint112 r0, uint112 r1, uint32) {
                        reserve0 = r0;
                        reserve1 = r1;
                        
                        router = factoryToRouter[factory];
                        if (router != address(0)) {
                            success = true;
                        }
                    } catch {}
                } catch {}
            } catch {}
        } catch {}
    }
    
    // Helper function to check if pair passes tax limit
    function _checkTaxLimit(
        address router,
        address token0,
        address token1,
        uint amountIn,
        uint maxTaxPermille
    ) private view returns (bool) {
        address[] memory path = new address[](2);
        path[0] = token0;
        path[1] = token1;
        
        try IRouter(router).getAmountsOut(amountIn, path) returns (uint[] memory buyOuts) {
            if (buyOuts.length < 2) return false;
            
            address[] memory reversePath = new address[](2);
            reversePath[0] = token1;
            reversePath[1] = token0;
            
            try IRouter(router).getAmountsOut(buyOuts[1], reversePath) returns (uint[] memory sellOuts) {
                if (sellOuts.length < 2) return false;
                
                uint minReturn = amountIn - (amountIn * maxTaxPermille / 1000);
                return sellOuts[1] >= minReturn;
            } catch {
                return false;
            }
        } catch {
            return false;
        }
    }
    
    function checkPair(address pairAddress, uint amountIn, uint maxTaxPermille) external view returns (Result memory r) {        
        // Initialize result with default values
        r.success = false;
        
        // Skip processing if pair address is zero
        if (pairAddress == address(0)) return r;
        
        // Get pair data
        bool success;
        address token0;
        address token1;
        address factory;
        uint112 reserve0;
        uint112 reserve1;
        address router;
        
        (success, token0, token1, factory, reserve0, reserve1, router) = _getPairData(pairAddress);
        
        // If we couldn't get pair data or there's no router, return early
        if (!success) return r;
        
        // Check tax limits
        bool passedTaxCheck = _checkTaxLimit(router, token0, token1, amountIn, maxTaxPermille);
        
        // Populate result if tax check passed
        if (passedTaxCheck) {
            r.success = true;
            r.token0 = token0;
            r.token1 = token1;
            r.factory = factory;
            r.reserve0 = reserve0;
            r.reserve1 = reserve1;
        }
        
        return r;
    }
}
  • Komunikasi Berbasis Peristiwa: Setelah menerima dan memproses peristiwa ini, Reader menormalkan data dan mengirimkan pembaruan (misalnya, nilai cadangan baru untuk kumpulan tertentu) sebagai pesan melalui saluran Go ke Market Graph Service.

Layanan Peta Pasar: Peta Pasar DeFi

Market Graph Service adalah unit intelijen pusat, mempertahankan representasi real-time, dalam memori pasar DeFi.directed graphdi mana :

  • Node: mewakili cryptocurrencies individu (misalnya, WETH, USDC, DAI).
  • Edges: mewakili pool likuiditas di berbagai DEXes (misalnya, Uniswap V2 ETH/DAI pool, SushiSwap USDC/WETH pool).
  • Struktur Data dan Pembaruan: Layanan ini menerima pembaruan dari Layanan Pembaca Data Blockchain melalui saluran.Setelah menerima data cadangan baru untuk kolam, itu memperbarui tepi yang sesuai di grafik.
  • Akurasi dengan BigInt: Semua perhitungan yang melibatkan jumlah token dan nilai tukar menggunakan paket matematika / besar Go (BigInt atau BigFloat). Ini sangat penting untuk mempertahankan akurasi arbitrase, mencegah ketidakakuratan titik-titik yang dapat menyebabkan kesempatan yang hilang atau perhitungan keuntungan yang salah.
  • Arbitration Path Detection: Bellman-Ford Algorithm: Di jantung layanan ini adalah fungsi FindArbitrage, yang menggunakan algoritma diagram traversal, khususnya Bellman-Ford. Algoritma ini unik mampu menemukan siklus negatif dalam grafik, yang persis apa yang sesuai dengan peluang arbitrase dalam model pasar kami (di mana nilai tukar logaritmik digunakan sebagai beban tepi). Tidak seperti banyak algoritma teori grafik lainnya yang berfokus pada menemukan jalur yang paling efisien, kemampuan Bellman-Ford untuk mendeteksi siklus negatif membuatnya sangat efisien untuk kedua DeFi dan aplikasi keuangan kuantitatif di mana keuntungan dicari dari perbedaan siklik.

Layanan Strategi Arbitrase: Identifikasi dan Optimalisasi Keuntungan

Mendaftar untuk update acara dariMarket Graph ServiceArbitrase Strategy Service terus memantau grafik pasar untuk jalur arbitrase yang baru terdeteksi.

  • Evaluasi Kesempatan: Setiap kali grafik diperbarui atau jalur arbitrase potensial diidentifikasi oleh FindArbitrage, layanan ini meluncur ke dalam tindakan.
  • Optimal Input Amount Calculation (Convex Optimization): Langkah penting adalah menentukan jumlah input optimal (dx) untuk urutan arbitrase. Ini adalah masalah non-trivial, karena profitabilitas adalah fungsi non-linear dari jumlah input, seperti yang ditunjukkan dalam makalah ‘An analysis of Uniswap markets’. Ini dipengaruhi oleh slippage dan biaya di antara beberapa swap. Layanan memecahkan ini sebagai masalah optimasi konveksi, menggunakan paket Go’s gonum/optimize. Ini memastikan bahwa jumlah input yang dipilih memaksimalkan keuntungan bersih setelah akuntansi untuk semua variabel.
  • Simulasi Swap: Sebelum melakukan transaksi, layanan melakukan eksekusi simulasi semua swap dalam jalur arbitrase yang terdeteksi menggunakan rumus produk konstan dan jumlah input optimal yang dihitung. Selama simulasi ini, jumlah output minimum juga ditetapkan untuk setiap langkah swap menengah. ini memastikan bahwa dalam kasus output aktual yang tidak terduga rendah (misalnya, karena fluktuasi harga tiba-tiba atau sliding tinggi di rantai), transaksi akan kembali dengan kerugian gas minimal, bukannya melanjutkan dengan perdagangan yang tidak menguntungkan atau kalah.
  • Semua Biaya: Termasuk Biaya Perdagangan DEX (misalnya, 0,3% untuk Uniswap V2).
  • Slippage: Memodelkan dengan tepat dampak harga dari setiap perdagangan dalam urutan.
  • Gas Costs: An estimate of the gas fees required for the entire transaction, considering the chain (Base) and current network conditions.
  • Hanya jika keuntungan bersih yang dihitung setidaknya 0,5% dari jumlah input awal (atau ambang batas yang dapat dikonfigurasi) adalah peluang yang dianggap layak. ambang batas ini memastikan bahwa upaya dan risiko mengirimkan transaksi dibenarkan oleh pengembalian yang substansial.
  • Pemberitahuan untuk Eksekusi: Jika peluang yang menguntungkan memenuhi kriteria, Layanan Strategi Arbitrase mengumpulkan semua rincian yang diperlukan - urutan swap yang diatur (edge), jumlah input optimal, dan parameter lain yang relevan - dan mengirimkan pemberitahuan melalui saluran Go ke Layanan Pembuat Transaksi.

Layanan Pembuat Transaksi: Eksekusi Swift

Transaction Builder Service adalah lengan eksekusi bot, yang ditugaskan dengan cepat membangun dan mengirimkan transaksi arbitrase ke blockchain. kecepatan adalah prioritas di sini, karena peluang sangat sensitif waktu.

  • Konstruksi Transaksi: Setelah menerima kesempatan dari Layanan Strategi Arbitrase, layanan ini segera mulai membangun transaksi blockchain atomik.
  • Smart Contract Interaction (Atomic Swaps): Layanan ini berinteraksi dengan kontrak pintar kustom yang dirancang khusus untuk melakukan semua operasi arbitrase (multiple swaps) dalam satu transaksi atomik. kontrak ini juga menangani persetujuan token dalam aliran transaksi yang sama. logika ini sangat penting untuk mencegah frontrunning atau backrunning di tengah urutan arbitrase, karena seluruh operasi berhasil atau gagal sebagai satu unit.
  • Berikut adalah fungsi Solidity yang menangani eksekusi arbitrase tanpa pinjaman flash, yang mengharuskan pemilik (bot) untuk mendanai jumlah awalIn:
struct SwapStep {
      address router;
      address[] path;
      uint minOut;
}

function executeArb(
    address inputToken,
    uint amountIn,
    SwapStep[] calldata steps,
    uint minFinalOut
) external onlyOwner returns (uint finalAmountOut) {
    require(steps.length > 0, "No steps");

    // Transfer tokens from msg.sender to contract
    require(IERC20(inputToken).transferFrom(msg.sender, address(this), amountIn), "Transfer in failed");

    address currentToken = inputToken;
    uint currentAmount = amountIn;

    for (uint i = 0; i < steps.length; i++) {
        SwapStep calldata step = steps[i];
        require(step.path[0] == currentToken, "Path mismatch");

        address outputToken = step.path[step.path.length - 1];

        // Save balance before swap
        uint balanceBefore = IERC20(outputToken).balanceOf(address(this));

        // Safe approve
        require(IERC20(currentToken).approve(step.router, 0), "Reset approve failed");
        require(IERC20(currentToken).approve(step.router, currentAmount), "Approve failed");

        IUniswapV2Router(step.router).swapExactTokensForTokens(
            currentAmount,
            step.minOut,
            step.path,
            address(this),
            block.timestamp
        );

        uint balanceAfter = IERC20(outputToken).balanceOf(address(this));
        uint received = balanceAfter - balanceBefore;

        require(received >= step.minOut, "Slippage too high");

        currentToken = outputToken;
        currentAmount = received;
    }

    require(currentAmount >= minFinalOut, "Final output too low");

    require(IERC20(currentToken).transfer(owner, currentAmount), "Final transfer failed");

    return currentAmount;
}
  • Integrasi Pinjaman Flash: Jika jumlah optimal untuk arbitrase membutuhkan pinjaman flash, pembangun mengintegrasikan logika pinjaman flash (meminjam → melakukan swap → membayar) ke dalam satu transaksi tunggal, tak terpisahkan, menggunakan kontrak khusus yang memfasilitasi operasi atom ini melalui antarmuka FlashLoanSimple Aave.
  • Berikut adalah fungsi kontrak Solidity executeOperation (bagian dari kontrak FlashLoanReceiver yang lebih besar) yang dipanggil oleh Aave Pool dan berisi logika arbitrase menggunakan dana yang dipinjamkan:
function startArbitrage(
      address token,
      uint256 amount,
      SwapStep[] calldata steps,
      uint256 minFinalOut
) external onlyOwner {
    bytes memory params = abi.encode(steps, minFinalOut);
    POOL.flashLoanSimple(address(this), token, amount, params, 0);
}

function executeOperation(
    address asset,
    uint256 amount,
    uint256 premium,
    address initiator,
    bytes calldata params
) external override returns (bool) {
    require(msg.sender == address(POOL), "Untrusted lender");
    require(initiator == address(this), "Unauthorized initiator");

    (SwapStep[] memory steps, uint256 minFinalOut) = abi.decode(params, (SwapStep[], uint256));

    // Execute the arbitrage
    address currentToken = asset;
    uint currentAmount = amount;

    for (uint i = 0; i < steps.length; i++) {
        SwapStep memory step = steps[i];
        require(step.path[0] == currentToken, "Path mismatch");

        address outputToken = step.path[step.path.length - 1];

        // Save balance before swap
        uint balanceBefore = IERC20(outputToken).balanceOf(address(this));

        // Safe approve
        require(IERC20(currentToken).approve(step.router, 0), "Reset approve failed");
        require(IERC20(currentToken).approve(step.router, currentAmount), "Approve failed");

        IUniswapV2Router(step.router).swapExactTokensForTokens(
            currentAmount,
            step.minOut,
            step.path,
            address(this),
            block.timestamp
        );

        uint balanceAfter = IERC20(outputToken).balanceOf(address(this));
        uint received = balanceAfter - balanceBefore;

        require(received >= step.minOut, "Slippage too high");

        currentToken = outputToken;
        currentAmount = received;
    }

    require(currentAmount >= amount + premium, "Insufficient profit");
    require(currentAmount >= minFinalOut, "Final output too low");

    // Repay the loan
    require(IERC20(asset).approve(address(POOL), amount + premium), "Approval failed");
    
    // Transfer profits to owner
    uint profit = IERC20(asset).balanceOf(address(this)) - (amount + premium);
    if (profit > 0) {
        require(IERC20(asset).transfer(owner, profit), "Profit transfer failed");
    }

    return true;
}
  • Estimasi dan Harga Gas: Dinamis memperkirakan gas yang dibutuhkan untuk transaksi dan menetapkan harga gas yang tepat (atau biaya prioritas pada L2 seperti Base) untuk memastikan penyertaan tepat waktu dalam blok.
  • Transaction Dispatch: Once constructed, the signed transaction is dispatched to the Base blockchain node. The choice of Base is strategic: unlike Ethereum L1, Base’s current architecture does not feature a publicly visible mempool in the traditional sense. This means that transactions are less susceptible to direct generalized frontrunning by bots scanning the mempool. While Maximal Extractable Value (MEV) still exists on L2s, the mechanisms for its extraction differ from L1, and direct mempool sniping is significantly reduced, offering a more predictable execution environment for arbitrageurs.
  • Feedback Asynchronous: Setelah mengirimkan transaksi, layanan mengirimkan pemberitahuan ke Layanan Honeywall untuk menandakan bahwa transaksi telah dimulai dan membutuhkan pemantauan.

Honeywall Service: Validasi dan Keamanan Setelah Eksekusi

Layanan Honeywall bertindak sebagai pemeriksa pasca-eksekusi kritis dan lapisan keamanan yang kuat untuk bot arbitrase. perannya adalah untuk memvalidasi hasil transaksi yang dilakukan dan melindungi terhadap aktor jahat.

  • Transaction Outcome Monitoring: Setelah Transaction Builder mengirimkan transaksi, Honeywall Service memantau penyertaan dalam blok dan hasilnya.
  • Logging keuntungan: Jika transaksi berhasil dan menghasilkan keuntungan (seperti yang diharapkan dari simulasi), rincian keuntungan dicatat untuk pelacakan kinerja dan analisis.
  • Analisis kegagalan: Dalam kasus kegagalan transaksi, Honeywall menganalisis alasan untuk revert.
  • Honeypot / Scam Detection dan Blacklisting: Fitur keamanan utama adalah kemampuan untuk mengidentifikasi token "honeypot" atau kolam yang menerapkan logika menipu (misalnya, memungkinkan pembelian tetapi mencegah penjualan, atau mengenakan pajak tersembunyi yang berlebihan pada penjualan).
  • Integrasi Penyedia Eksternal: Ini mengintegrasikan dengan penyedia eksternal atau database kontrak honeypot yang dikenal untuk merujuk pasangan yang digunakan dalam transaksi yang gagal, sehingga mengidentifikasi penipuan potensial.
  • Dynamic Blacklisting: Jika sepasang atau kolam tertentu diidentifikasi sebagai honeypot atau bermasalah karena pajak tinggi yang tidak terduga, itu segera ditambahkan ke daftar hitam yang didukung oleh database.
  • Integrasi Filter Bloom: Daftar hitam ini dikelola secara efisien melalui mekanisme filter Bloom. Ini memungkinkan Layanan Pembaca Data Blockchain untuk dengan cepat memeriksa pasangan yang baru diamati terhadap daftar hitam sebelum bahkan mengumpulkan cadangan mereka atau menambahkan mereka ke grafik pasar.

Kesimpulan dari Desain Arsitektur

Arsitektur modular, didorong oleh peristiwa yang diimplementasikan di Go, dikombinasikan dengan layanan khusus untuk pengambilan data, pemodelan pasar, optimasi peluang, eksekusi cepat, dan keamanan yang kuat, membentuk tulang punggung dari robot arbitrase kinerja tinggi kami. desain ini memastikan bahwa sistem dapat bereaksi dengan kecepatan yang tak tertandingi terhadap peluang pasar yang melelahkan sambil juga mengurangi risiko signifikan yang melekat pada DeFi “Dark Forest.”

Deteksi Kesempatan dan Eksekusi Optimal: Otak Bot

Kecerdasan sejati dari bot arbitrase terletak pada kemampuannya untuk dengan cepat dan akurat mengidentifikasi peluang menguntungkan dalam pasar yang terus berubah, dan kemudian untuk mengoptimalkan eksekusi untuk pengembalian maksimum. bab ini menyelidiki algoritma inti dan model matematika yang mendukung proses pengambilan keputusan bot kami, dari memetakan pasar sebagai grafik untuk secara akurat menghitung ukuran perdagangan optimal dan mensimulasikan hasil.

Model Pasar DeFi Sebagai Grafik

Seperti yang diperkenalkan dalam gambaran arsitektur, Market Graph Service kami mewakili lanskap DeFi sebagai grafik yang diarahkan. dalam model ini, token individual (misalnya, WETH, DAI, USDC) berfungsi sebagainodes, sementara pool likuiditas di berbagai bursa terdesentralisasi (DEX) bertindak sebagaiedgesBerat setiap tepi mewakili biaya transaksi melalui kolam itu.

Untuk secara efisien mendeteksi peluang arbitrase, yang dimanifestasikan sebagai siklus yang menguntungkan, kami mengubah masalah menemukan urutan perdagangan yang menguntungkan menjadi menemukannegative cycleTransformasi ini dicapai dengan menerapkan fungsi logaritma pada nilai tukar.

Kebutuhan Logaritma untuk Deteksi Siklus

Ide inti di balik arbitrase adalah untuk melipatgandakan jumlah awal dengan serangkaian nilai tukar untuk berakhir dengan lebih dari aset asli.TokenXdan perdagangan untukTokenYSetelah ituTokenYUntukTokenZDan akhirnyaTokenZKembali keTokenXJumlah akhir kita adalah :

Bekerja dengan produk dalam algoritma graf adalah rumit. teknik umum dalam keuangan komputasi untuk mengubah masalah multiplikasi menjadi aditif adalah untuk menerapkan logaritma.

Untuk mendapatkan siklus yang menguntungkan, kita perluln (Sejarah) > ln (A)yang berartiln(RateX→Y) + ln(RateY→Z) + ln(RateZ→X) > 0Namun, algoritma jalur terpendek khas (seperti Bellman-Ford, yang kami gunakan) dirancang untuk menemukan jalur dengan minimalsumUntuk membuat siklus yang menguntungkan muncul sebagai “siklus negatif” di grafik kami, kami hanya menyangkal tingkat logaritma:

ln(RateX→Y) + ln(RateY→Z) + ln(RateZ→X) > 0

Dengan transformasi ini, jumlah beban negatif yang menghasilkan nilai negatif (yaitu, siklus negatif) secara langsung menunjukkan peluang arbitrase yang menguntungkan.

Menjalankan akurasi denganBigInt

Jumlah token dalam DeFi dapat bervariasi, mulai dari fraksi kecil (misalnya, untuk token ERC-20 dengan 18 tempat desimal) hingga jumlah yang sangat besar (misalnya, stablecoins). Heterogenitas ekstreme dalam ukuran, mencakup hingga 18 angka signifikan, membuat aritmatika titik mengambang standar sangat rentan terhadap kesalahan akurasi. Kesalahan seperti itu, meskipun tampaknya kecil, dapat menyebabkan peluang yang tidak teridentifikasi atau, lebih buruk lagi, perdagangan yang tidak menguntungkan.

Untuk mengatasi ini, layanan Market Graph kami, dan sebenarnya semua perhitungan yang melibatkan jumlah token dan nilai tukar dalam bot, menggunakan Go’smath/bigPaket ini secara khususBigIntUntuk aritmatika danBigFloatuntuk operasi titik-titik mengambang jika diperlukan. sementaraBigFloatmenawarkan presisi arbitrase, menerapkanlogDuaBigIntatauBigFloatNilai-nilai membutuhkan perlakuan yang hati-hati, sebagai standarmath.LogFungsi yang digunakan pada nativefloat64 types. Custom implementations or external libraries capable of arbitrary-precision logarithms are essential here.

func getLogRate(reserve0, reserve1 *big.Int) *big.Float {
	const prec = 1024
	resIn := new(big.Float).SetPrec(prec).SetInt(reserve0)
	resOut := new(big.Float).SetPrec(prec).SetInt(reserve1)

	// Effective Rate
	rate := new(big.Float).SetPrec(prec).Quo(resOut, resIn)
	logRate := bigfloat.Log(rate)

	return logRate.Neg(logRate)
}

Arbitrase Path Deteksi: The Bellman-Ford Algorithm

Setelah pasar DeFi dimodelkan dengan tepat sebagai grafik dengan beban tepi negatif logaritmik, tugas menemukan peluang arbitrase berkurang menjadi mengidentifikasinegative cyclesUntuk tujuan ini, kami menggunakanBellman-Ford algorithm.

Diberi nama setelah Richard Bellman dan Lester Ford Jr., Bellman-Ford adalah algoritma jalur terpendek yang serbaguna yang mampu menangani grafik dengan beban tepi negatif. Tidak seperti algoritma Dijkstra, yang gagal dalam kehadiran siklus negatif, Bellman-Ford dirancang khusus untuk mendeteksi mereka. makna sejarahnya melampaui ilmu komputer teoritis; ia telah menemukan aplikasi di berbagai bidang, termasuk routing jaringan (di mana ia membantu menemukan jalur termurah dengan biaya yang bervariasi) dan, secara kritis, dalam keuangan kuantitatif untuk mengidentifikasi peluang perdagangan menguntungkan di pasar mata uang.

Algoritma bekerja dengan melonggarkan tepi secara iteratif, secara bertahap menemukan jalur yang lebih pendek ke semua node dari satu sumber. Jika, setelah iterasi ÁthaV Cliath−1 (di mana ÁthaV Cliath adalah jumlah puncak), iterasi N-th tambahan menemukan jalur yang masih dapat “relaksasi” (yaitu, jalur yang lebih pendek dapat ditemukan), itu menunjukkan adanya siklus negatif. Properti ini membuatnya sempurna untuk kasus penggunaan kami: siklus negatif melibatkan urutan perdagangan yang menghasilkan keuntungan bersih, persis apa yang dicari oleh bot arbitrase.


type Edge struct {
	Pair     string
	From     Token
	To       Token
	LogRate  *big.Float
	Reserve0 *big.Int
	Reserve1 *big.Int
	Dex      string
	MinOut   *big.Int
}

type Graph struct {
	nodes         map[string]Token
	Edges         map[string][]*Edge
	pairChan      *chan GraphMessage
	dexCheckChan  *chan DexDexMessage
	subscriptions []*chan time.Duration
	mu            sync.RWMutex
}

// Bellman-Ford algorithm to find arbitrage cycles
func (g *Graph) FindArbitrage(source Token) ([]*Edge, bool) {
	sourceKey := source.Address

	g.mu.RLock()
	defer g.mu.RUnlock()

	distance := make(map[string]*big.Float)
	predecessor := make(map[string]*Edge)

	// 1. Init
	for token := range g.nodes {
		distance[token] = new(big.Float).SetInf(false)
	}
	distance[sourceKey] = new(big.Float).SetFloat64(0)

	// 2. Relax edges V-1 times
	for i := 0; i < len(g.nodes)-1; i++ {
		for _, edgeList := range g.Edges {
			for _, e := range edgeList {
				from := e.From.Address
				to := e.To.Address

				if !distance[from].IsInf() && new(big.Float).Add(distance[from], e.LogRate).Cmp(distance[to]) < 0 {
					distance[to].Add(distance[from], e.LogRate)
					predecessor[to] = e
				}
			}
		}
	}

	// 3. Negative cycle detection
	var cycleStartToken string
	for _, edgeList := range g.Edges {
		for _, e := range edgeList {
			from := e.From.Address
			to := e.To.Address
			if !distance[from].IsInf() && new(big.Float).Add(distance[from], e.LogRate).Cmp(distance[to]) < 0 {
				cycleStartToken = to
				break
			}
		}
		if cycleStartToken != "" {
			break
		}
	}

	if cycleStartToken == "" {
		return nil, false // No Arbitrage
	}

	// 4. detect first cycle node
	visited := make(map[string]bool)
	current := cycleStartToken
	for !visited[current] {
		visited[current] = true
		edge := predecessor[current]
		if edge == nil {
			return nil, false // missing edge
		}
		current = edge.From.Address
	}

	// 5. Complete cycle
	cycleStart := current
	cycle := []*Edge{}
	for {
		edge := predecessor[current]
		if edge == nil {
			return nil, false // missing edge
		}
		cycle = append(cycle, edge)
		current = edge.From.Address
		if current == cycleStart {
			break
		}
	}

	// 6. Invert cycle
	for i, j := 0, len(cycle)-1; i < j; i, j = i+1, j-1 {
		cycle[i], cycle[j] = cycle[j], cycle[i]
	}

	return cycle, true
}

Cara Menghitung Input Optimal: Maksimalkan Keuntungan

Setelah siklus negatif (peluang arbitrase) diidentifikasi, langkah kritis berikutnya adalah untuk menentukanoptimal input amount(dx) untuk perdagangan awal dalam urutan. ini tidak arbitrase; profitabilitas peluang arbitrase adalah fungsi non-linear dari ukuran perdagangan karena slippage inherent dan biaya yang terkait dengan swap AMM.

Seperti yang dijelaskan dalam “An analysis of Uniswap markets”, rumus produk konstan secara intrinsik menyiratkan konveksi dalam hubungan antara jumlah input dan output. Secara khusus, seiring dengan meningkatnya ukuran perdagangan, nilai tukar yang efektif memburuk karena invarians pool.

Maksimalisasi keuntungan adalah suatuconvex optimization problemUntuk serangkaian N swap dalam jalur arbitrase, jumlah output akhir (dan karenanya keuntungan) dapat dinyatakan sebagai fungsi dari jumlah input awal (dx ). Sementara solusi analitis yang tepat untuk arbitrase multi-kaki dapat rumit, terutama dengan struktur biaya yang bervariasi dan kurva sliding di seluruh AMM yang berbeda, fungsi yang mewakili keuntungan minus biaya (termasuk gas) umumnya konveks.

Layanan Strategi Arbitrase kami mengatasi ini dengan menggunakan penyelesai optimasi dari Go’s.gonum/optimizeSolver ini mengambil fungsi yang mewakili keuntungan bersih (profit dari swap minus biaya gas yang diperkirakan dan premi pinjaman flash) dan menemukan jumlah input yang memaksimalkan nilai ini.amountOutFormula yangdy = (x + dx) / (dx⋅ y)untuk setiap langkah dalam jalur arbitrase, memperhitungkan cadangan interim, biaya, dan slippage pada setiap tahap.

func getOptimalAmoutIn(edges []*Edge, decimals int) (*float64, error) {
	factor := math.Pow10(decimals)
	intMax, _ := constants.GetRouterReserveFromToken(edges[0].From.Address)

	maxCapital := new(big.Float).Mul(new(big.Float).SetInt64(intMax), big.NewFloat(factor))
	fee := big.NewFloat(0.997)

	problem := optimize.Problem{
		Func: func(x []float64) float64 {
			delta := big.NewFloat(x[0])
			if delta.Cmp(big.NewFloat(0)) < 0 || delta.Cmp(maxCapital) > 0 {
				return math.Inf(1)
			}

			delta_i := new(big.Float).Set(delta)
			for _, edge := range edges {
				effectiveIn := new(big.Float).Mul(delta_i, fee)
				reserveIn := new(big.Float).SetInt(edge.Reserve0)
				reserveOut := new(big.Float).SetInt(edge.Reserve1)

				num := new(big.Float).Mul(reserveOut, effectiveIn)
				denom := new(big.Float).Add(reserveIn, effectiveIn)
				delta_i = new(big.Float).Quo(num, denom)
			}

			profit := new(big.Float).Sub(delta_i, delta)
			result, _ := profit.Float64()
			return -result
		},
	}

	result, err := optimize.Minimize(problem, []float64{1.0}, nil, nil)
	if err != nil {
		return nil, err
	}

	return &result.X[0], nil
}

Simulasi swap dan penilaian profitabilitas

Sebelum setiap transaksi dikirim, Layanan Strategi Arbitrase melakukan tindakan yang teliti.simulated executionLangkah ini sangat penting untuk memverifikasi profitabilitas aktual, mengingat kondisi pasar real-time dan parameter yang tepat dari perdagangan yang diusulkan.

The simulation uses the current reserves of the involved liquidity pools and the calculated optimal input amount. For each step in the multi-leg path, it applies the specific AMM formula (e.g., the constant product formula for Uniswap V2-like pools) to calculate the expected output:

func (ab *ArbitrageBuilderV2) calculateProfitabilityWithSlippage(edges []*Edge, decimals int) (*big.Float, *big.Float, error) {
	opt, err := getOptimalAmoutIn(edges, decimals)
	if err != nil {
		return nil, nil, err
	}
	optBig := new(big.Float).SetFloat64(*opt)
	amount := new(big.Float).Set(optBig)

	fee := big.NewFloat(0.997)

	for _, edge := range edges {
		if edge.Reserve0 == nil || edge.Reserve1 == nil ||
			edge.Reserve0.Cmp(big.NewInt(0)) == 0 || edge.Reserve1.Cmp(big.NewInt(0)) == 0 {
			return nil, nil, errors.New("edge has invalid reserves")
		}

		reserveIn := new(big.Float).SetInt(edge.Reserve0)
		reserveOut := new(big.Float).SetInt(edge.Reserve1)

		amountInWithFee := new(big.Float).Mul(amount, fee)
		if amountInWithFee.Cmp(reserveIn) >= 0 {
			return big.NewFloat(-1.0), nil, errors.New("amount exceeds available reserves")
		}

		// "x * y = k"
		numerator := new(big.Float).Mul(reserveOut, amountInWithFee)
		denominator := new(big.Float).Add(reserveIn, amountInWithFee)
		amountOut := new(big.Float).Quo(numerator, denominator)

		amount = amountOut
	}

	profit := new(big.Float).Sub(amount, optBig)
	profit.Sub(profit, ab.EstimateGasCost(len(edges)))
	profit.Sub(profit, new(big.Float).Mul(optBig, big.NewFloat(0.005)))

	normalizedProfit := new(big.Float).Quo(profit, new(big.Float).SetFloat64(math.Pow10(decimals)))
	return normalizedProfit, optBig, nil
}

Selain itu, simulasi juga mencakupminimum output amount (minOut)perhitungan untuk setiap langkah. yaituminOutNilai-nilai dihasilkan dari output-output yang diharapkan dan ditetapkan sebagai parameter dalam transaksi on-chain yang sebenarnya.Jika, karena latensi jaringan, frontrunning, atau kondisi pasar yang tidak terduga, hasil swap on-chain yang sebenarnya kurang dari yang ditentukanminOutMekanisme ini adalah perlindungan penting, mencegah bot dari menyelesaikan urutan perdagangan yang tidak menguntungkan dan membatasi kerugian hanya untuk gas yang dihabiskan pada transaksi yang terbalik.

Hanya jika keuntungan bersih akhir, setelah semua biaya, slippage, biaya gas, dan premi pinjaman flash, melebihiprofit threshold(misalnya, 0,5% dari jumlah input awal) adalah peluang yang dianggap layak dan ditransfer ke Transaction Builder Service untuk eksekusi. ambang batas ini memastikan bahwa bot hanya mengejar peluang dengan margin yang cukup signifikan untuk membenarkan biaya komputasi dan pada rantai.

Transaksi Teknik: Eksekusi Cepat di Hutan Gelap

Mengidentifikasi peluang arbitrase yang menguntungkan hanyalah setengah dari pertempuran; yang lain, mungkin lebih penting, setengahnya terletak pada kemampuan untuk melakukan perdagangan dengan kecepatan dan keandalan yang tak tertandingi. Dalam “Dark Forest” hiper-kompetitif DeFi, di mana peluang melelahkan dan bot canggih hidup untuk setiap milisekund, teknik transaksi menjadi bentuk seni.Transaction Builder Servicedirancang untuk memastikan eksekusi cepat dan aman.

Imperatif kecepatan

Jendela profitabilitas untuk peluang arbitrase pada pertukaran terdesentralisasi sering diukur dalam milisekund. Perbedaan harga dengan cepat terdeteksi dan dimanfaatkan oleh banyak sistem otomatis, menciptakan perlombaan yang sengit untuk menjadi yang pertama untuk memasukkan transaksi yang menguntungkan ke dalam blok baru. Setiap penundaan, meskipun kecil, dapat mengakibatkan peluang tersebut disita oleh pesaing, menyebabkan transaksi yang gagal dan biaya gas yang terbuang. Oleh karena itu, setiap keputusan desain dalam Layanan Transaction Builder ditujukan untuk meminimalkan latensi pada setiap langkah yang mungkin, mulai dari konstruksi transaksi hingga pengiriman jaringan.

Optimasi In-Memory untuk Transaksi Instant

Untuk mencapai kecepatan yang diperlukan, sistem kami memprioritaskan memiliki semua komponen transaksi penting yang tersedia dalam memori, menghilangkan operasi I/O yang mahal atau panggilan pada rantai selama fase pembuatan transaksi kritis.

  • Pre-Parted dan Packed ABIs: Smart Contract Application Binary Interfaces (ABIs) mendefinisikan bagaimana berinteraksi dengan kontrak. Alih-alih menganalisa definisi ABI dan panggilan fungsi pengkodean pada fly untuk setiap transaksi, sistem kami pre-Partes dan membungkus struktur data ABI yang diperlukan dan selektor fungsi ke dalam rangkaian byte mentah[]. Urutan byte pre-computed ini untuk interaksi kontrak umum (misalnya, swapExactTokensForTokens, flashLoanSimple, transferFrom) disimpan dalam memori. Ketika kesempatan arbitrase diidentifikasi, Transaction Builder dapat dengan cepat mengumpulkan data panggilan dengan hanya menghubungkan komponen pre-packed ini dengan parameter khusus perdagangan, secara signifikan mengurangi waktu proses.
  • Cached On-Chain Data untuk Bidang Transaksi: Untuk menghindari panggilan berlebihan pada rantai untuk metadata transaksi, struktur utilitas khusus di dalam bot mempertahankan nilai kritis, sering diperbarui dalam memori:
  • Account Nonce: Nonce (jumlah transaksi yang dikirim dari alamat) sangat penting untuk mencegah serangan replay dan memastikan pemesanan transaksi. ia diambil sekali dan kemudian dikelola secara bertahap dalam memori, dengan pengolahan kesalahan yang kuat untuk menyinkronkan kembali jika transaksi gagal atau tidak terduga dimasukkan keluar dari urutan.
  • Parameter Gas Optimal: Alih-alih menginterogasi jaringan untuk harga gas (atau biaya dasar / biaya prioritas pada rantai EIP-1559) untuk setiap transaksi, bot secara berkala mengambil parameter gas optimal.
  • Informasi Penandatanganan: Kunci pribadi dari dompet bot dan objek penandatanganan yang terkait (yang digunakan untuk menandatangani transaksi secara kriptografis) dimuat ke dalam memori saat inisialisasi.

Dengan menyimpan komponen penting ini dalam memori, Transaction Builder Service dapat membangun dan menandatangani transaksi blockchain lengkap hanya dalam mikrosekunder, siap untuk pengiriman langsung.

Pilihan Kontrak Pintar Dinamis: Pinjaman Flash vs. Swap Langsung

Layanan Strategi Arbitrase mengirimkan jalur arbitrase yang dioptimalkan dan jumlah input optimal yang dihitung ke Pembuat Transaksi.amountIndan apakah itu melebihi ambang modal yang telah ditentukan sebelumnya (atau jika strategi secara eksplisit memintanya), Transaction Builder secara dinamis memilih antara dua kontrak pintar utama untuk dilaksanakan:

  • Kontrak Eksekusi Swap Langsung: Untuk peluang yang dapat didanai secara langsung oleh modal yang dimiliki bot, pembangun menggunakan fungsi executeArb (atau serupa) pada kontrak proxy multi-swap yang disesuaikan. Seperti yang ditunjukkan dalam Bab 3, kontrak ini mengambil token input dari dompet bot dan melakukan seluruh urutan swap dalam satu transaksi atomik. pendekatan ini menghindari kompleksitas dan premium tambahan dari pinjaman flash ketika tidak diperlukan.
  • Flash Loan Integrated Contract: Ketika jumlah optimal yang dihitung untuk arbitrase jauh lebih besar dari modal yang tersedia dari bot, pembangun menargetkan kontrak pintar yang terpisah, disesuaikan yang dirancang untuk memulai dan mengelola pinjaman flash. Fungsi startArbitrage kontrak ini (seperti yang dijelaskan dalam Bab 3) meminta pinjaman flash dari protokol seperti Aave, yang kemudian memanggil kembali fungsi executeOperation kontrak. Dalam executeOperation, seluruh urutan arbitrase dilakukan menggunakan dana yang dipinjamkan, dan pinjaman flash (plus premium kecil) dikembalikan – semua dalam transaksi blockchain atomik tunggal. Ini memungkinkan bot untuk memanfaatkan peluang yang sangat besar dan menguntungkan tanpa memerlukan modal besar, mendemokratisasi akses ke arbitrase skala besar.

Pemilihan dinamis ini memastikan alokasi modal yang efisien dan eksekusi strategi yang optimal berdasarkan spesifikasi masing-masing peluang yang terdeteksi.

Mempool Dynamics: Navigasi Ethereum L1 vs Layer 2 Rantai

Aspek penting dari eksekusi arbitrase adalah memahami mekanisme propagasi transaksi blockchain, khususnyamempool.

  • Ethereum L1 Mempool: On Ethereum’s Layer 1, the mempool is a public, transparent waiting room for all pending transactions. Transactions broadcasted by users or bots are relayed to various nodes across the network, becoming visible to anyone monitoring the mempool. This transparency is the breeding ground for generalized frontrunning bots (often referred to as “searchers” or “MEV bots”). These sophisticated entities continuously scan the mempool for profitable transactions (e.g., large swaps that cause significant price impact, liquidations, or other arbitrage attempts). Upon detecting such a transaction, they quickly construct an identical or similar transaction, replace the original recipient address with their own, and submit it with a higher gas price (or higher priority fee in EIP-1559) to ensure their transaction is included in the block before the original, thereby stealing the profit. This competitive landscape makes direct arbitrage on L1 highly challenging without leveraging specialized MEV relays.

  • Layer 2 (L2) Chains and Reduced Mempool Visibility (e.g., Base): Our bot strategically operates on Base, an EVM-compatible Layer 2 blockchain. The architecture of many L2s, including Base, fundamentally alters the traditional L1 mempool dynamic. Base does not currently expose a publicly visible mempool in the same manner as Ethereum Layer 1. Instead, transactions are typically sent directly to a centralized sequencer or a private mempool before being batched and committed to the L1.

    This architectural difference significantly reduces the direct threat of generalized frontrunning. While MEV still exists on L2s (e.g., through sequencer-controlled ordering or other means), the immediate, public visibility of pending transactions that enables L1 frontrunning is largely absent. This provides a more predictable and secure execution environment for our arbitrage transactions, as the bot’s crafted atomic operations are less likely to be “sniped” before they even reach a block producer. This improved execution predictability contributes directly to higher success rates for profitable arbitrages.

Kecepatan dan Keamanan Node: Dasar Eksekusi yang Terpercaya

Koneksi ke node blockchain adalah satu titik masuk dan keluar untuk semua data dan transaksi. kecepatannya dan keamanan adalah yang utama:

  • Koneksi Node Berkinerja Tinggi: Transaction Builder Service menghubungkan ke penyedia node berkinerja tinggi yang didedikasikan (misalnya, Alchemy, Infura, atau node self-hosted). Koneksi cepat dan latensi rendah sangat penting untuk meminimalkan waktu antara penandatanganan transaksi dan penyebaran ke jaringan.
  • Keamanan dan Integritas Node: Keamanan node yang terhubung sama pentingnya. Menggunakan penyedia node yang dapat diandalkan atau memastikan node yang sangat aman adalah penting untuk mencegah serangan manusia-in-the-middle atau manipulasi data. Node yang terpengaruh berpotensi bocorkan kunci pribadi, menyuntikkan transaksi berbahaya, atau memanipulasi data, menyebabkan kerugian bencana. Kepercayaan sistem kami pada titik akhir RPC pribadi (jika tersedia dari penyedia) dan saluran komunikasi yang aman (https untuk HTTP, wss untuk WebSockets) memperkuat sikap keamanan ini.

Dengan berhati-hati mengoptimalkan kecepatan pada setiap lapisan, mulai dari struktur data dalam memori dan pre-komputasi hingga pemilihan rantai strategis dan infrastruktur node yang kuat, arbitrage bot kami dirancang untuk melampaui kompetitor dan dengan aman memanfaatkan peluang yang melelahkan dalam lanskap DeFi.

Navigasi Hutan Gelap: Tantangan, Etika, dan Prospek Masa Depan

Membangun dan mengoperasikan bot arbitrase di DeFi “Dark Forest” adalah bukti kekuatan teknologi terdesentralisasi, tetapi juga menimbulkan tantangan yang signifikan dan pertimbangan etis.

Pertempuran konstan melawan aktor jahat: Peran Bloom Filter

Optimisme awal yang mengelilingi sifat DeFi yang tidak diperbolehkan, sayangnya, telah dikurangi oleh proliferasi aktor jahat.Honeywall ServiceIni berfungsi sebagai garis pertahanan terakhir yang penting, tetapi kecerdasan para pemain jahat ini terus-menerus menuntut evolusi countermeasures.

Salah satu komponen penting dari pertahanan ini adalahBloom filterSebuah filter Bloom adalah struktur data probabilistik yang dapat dengan cepat dan efisien menguji apakah suatu elemen adalah anggota set. Ini sangat efisien ruang tetapi membawa probabilitas kecil dari "positif palsu" (menunjukkan bahwa suatu elemen berada dalam set ketika tidak ada), meskipun tidak pernah "negatif palsu." Dalam konteks kami, filter Bloom digunakan untuk pra-filter data peristiwa masuk dari Layanan Pembaca Data Blockchain. Ini berisi hash dari pasangan likuiditas berbahaya atau tinggi yang diketahui. Sebelum pemrosesan rinci atau pengambilan cadangan, pemeriksaan cepat terhadap filter Bloom dapat segera membuang sepasang masalah yang diketahui, mencegah sumber daya komputasi yang terbuang dan risiko potensial.

Meskipun pre-checks canggih yang diimplementasikan dalam kebiasaan kamiArbHelperMapKontrak pintar (terutama_checkTaxLimitlogika yang mensimulasikan swap round-trip untuk mengevaluasi pajak), beberapa pasangan jahat masih berhasil menghindari validasi on-chain awal ini.getAmountsOutfungsinya (diterapkan untuk pertanyaan harga) untuk mengembalikan hasil pajak yang tampaknya normal, namun, logika “honeypot” yang sebenarnya tertanam lebih dalam dalamswapExactTokensForTokensatau mendasaritransferFungsi-fungsi ini dapat mengenakan pajak tersembunyi yang berlebihan (misalnya, 99%) pada operasi penjualan, atau bahkan benar-benar membatasi penjualan, secara efektif menangkap dana.

Selama fase pengujian kami, kami menemukan sejumlah besar pasangan penipuan seperti itu. saya secara pribadi telah mengumpulkan beberapa pasangan alamat yang berhasil lulus awalgetAmountsOutpemeriksaan tetapi mengungkapkan pajak tersembunyi atau pembatasan penjualan hanya selama transaksi aktual (simulasi atau terbalik) dalam database lokal. file db ini akan tersedia secara publik di repositori GitHub proyek, berfungsi sebagai sumber daya komunitas untuk membantu orang lain menghindari jebakan ini. permainan kucing dan tikus yang sedang berlangsung menekankan kebutuhan untuk pemantauan berkelanjutan, blacklisting cepat, dan strategi pertahanan multi-layer.

Implikasi Etika dan Bayangan Hutan Gelap

Analogi “Dark Forest” tidak hanya cocok untuk persaingan antara bot, tetapi juga untuk lanskap etika DeFi yang lebih luas. efisiensi arbitrase, sementara penting untuk kesehatan pasar dan penemuan harga, datang dengan realitas yang tajam: keuntungan yang dihasilkan oleh arbitrase sering mewakili nilai yang diambil dari peserta pasar yang kurang canggih.

Budaya yang luas dariFOMO (Fear Of Missing Out), dikombinasikan dengan kurangnya pemahaman umum tentang mekanisme blockchain dan instrumen keuangan yang mendasarinya, membuat banyak pengguna ritel mudah menjadi mangsa dalam lingkungan ini. mereka memasuki pasar yang sangat volatile, berinteraksi dengan protokol baru, dan melakukan perdagangan tanpa kesadaran penuh tentang konsep seperti slippage, MEV, atau pajak kontrak tersembunyi.

Dinamika ini, sementara secara ekonomis logis bagi mereka yang memiliki alat-alat canggih, melemparkan bayangan pada reputasi teknologi terdesentralisasi. Narratif ini dapat dengan cepat bergeser dari “pemerintahkan keuangan” ke “perilaku predator,” mengganggu kepercayaan dalam ruang yang sebaliknya memegang janji yang besar. DeFi, pada intinya, bertujuan untuk mendemokrasi keuangan, menawarkan akses tanpa izin dan transparansi. Namun, sifat canggih dari MEV dan prevalensi penipuan dapat secara tidak sengaja merusak ideal-ideal ini, menciptakan sistem dua tingkat di mana hanya ahli teknologi yang benar-benar dapat bernavigasi dengan aman. Adalah penting bahwa, sebagai pembangun, kita mengakui dimensi etika ini dan mendorong pendidikan pengguna yang lebih besar, audit keamanan yang kuat, dan mekanisme yang melindungi peserta yang rentan.

Judul: Masih Menjelajah Hutan Gelap

Terlepas dari kompleksitas yang melekat dan tantangan yang terus-menerus dari lanskap DeFi, perjalanan rekayasa robot arbitrase ini telah menjadi validasi yang luar biasa dari prinsip-prinsip teoritis yang memenuhi implementasi praktis.speed, precision, and data-driven insights, mampu mendeteksi dan melaksanakan peluang arbitrase multi-kaki.

Awalnya, harapan umum di dalam “Dark Forest” adalah bahwa mayoritas nilai arbitrase akan segera ditangkap oleh pemain besar, dengan sumber daya yang baik, memanfaatkan node self-hosted dan akses langsung ke produsen blok.

Sementara arbitrase menguntungkan pada model AMM yang lebih tua seperti Uniswap V2 (yang terutama bergantung pada pool produk konstan) dapat menantang untuk mempertahankan jangka panjang karena meningkatnya biaya gas dan meningkatnya persaingan, “Dark Forest” terus berkembang. Implementasi yang lebih baru, seperti Uniswap V3’s Concentrated Liquidity AMMs (CLAMMs), memperkenalkan vektor arbitrase baru yang membutuhkan pemodelan yang lebih canggih tetapi sering menghasilkan pengembalian yang lebih tinggi karena peningkatan efisiensi modal. Selanjutnya, bidang yang berkembang dari arbitrase lintas rantai, memanfaatkan jembatan dan protokol komunikasi inter-blockchain, menyajikan perbatasan yang lebih luas dari perbedaan harga tambahan di berbagai jaringan blockchain. Perkembangan berkelanjutan ini menunjukkan bahwa lingkungan yang menantang ini akan tetap menjadi lahan yang

Jadi, sementara saya masih miskin, saya dapat dengan percaya diri mengatakan bahwa saya telah menjadi navigator hutan yang sangat baik.My compass is sharper, my map more detailed, and I understand the whispers of the canopy.

Proyek Repository

Bagi mereka yang bersemangat untuk menyelam lebih dalam ke dalam implementasi praktis dan data yang sangat nyata di balik beberapa "perangkap" yang kami diskusikan, versi yang disempurnakan dari basis kode kami dan database yang dipenuhi dengan pasangan token berbahaya yang diketahui tersedia di saya.Penyimpanan GitHub85 pasangan spesifik ini, meskipun secara numerik kecil, menghasilkan volume transaksi yang tidak proporsional karena mereka terus-menerus mencoba untuk menarik bot naif ke dalam perdagangan yang tidak menguntungkan.

Penyimpanan GitHub

Referensi

  • Dan Robinson, Georgios Konstantopoulos, “Ethereum adalah Hutan Gelap”,* Paradigma.
  • Guillermo Angeris, Hsien-Tang Kao, Rei Chiang, Charlie Noyes, dan Tarun Chitra. “An analysis of Uniswap markets”, Cryptoeconomic Systems.
  • Claudio Gebbia. “Analisis dan Implementasi Arbitrase Bots dalam Keuangan Terpusat dan Terdesentralisasi”, Universitas Zurich.
  • Y. Zhang, Z. Li, T. Yan, Q. Liu, N. Vallarano dan C. J. Tessone, “Maksimalisasi Keuntungan Dalam Lingkaran Arbitrase”.


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks