闇の森の中へ 1.導入 - 1.導入 - ある夜、投資会社パラダイムの研究員であるダン・ロビンソンは、Uniswap Discordチャンネルで緊急通話を見た。 別のユーザーに、しかしUniswap契約そのものに、彼らは回復しなく失われたように見えた。 2位 しかし、ロビンソンは希望の光を見たので、誰もが希望を引き起こすことができることに気づいた。 契約上の機能は、契約を強制し、それを呼び出した人に閉じ込められたトークンをリリースするための公開コマンドです。 burn ホワイトハットのヒーローになるチャンスを認識し、ロビンソンは救済取引を準備しましたが、彼は彼が一人ではないことを知っていました。Ethereum mempool - 待機中の取引のための公共の待合室 - は「一般化されたフロントランナー」として知られる洗練されたボットのための狩場です。これらの捕食者は継続的に利益を得る行動をスキャンし、直ちにそれをコピーし、オリジナルのアドレスを自分のものに置き換え、報酬を盗みます。 彼らを乗り越えるために、ロビンソンは、両方の部分を同時に採掘することを望んで、賢明な2つの部分の取引を策定し、遮断のためのウィンドウを残さなかった。それがうまくいかなかった。彼の最初の取引が現れた瞬間、ボットがそれを検出し、全体の戦略を複製し、ロビンソンの2つ目の取引が確認されるまで12000ドルを略奪した。 この事件について有名なエッセイの中で、ロビンソンはこの敵対的で目に見えない生態系に名前を付けました。 Ethereum is a Dark Forest. この記事では、ブロックチェーン取引のリアルタイムの操作とデータを読み取ることができるシステムの設計に注目し、仲裁を実行することを目指します。 「DELVE IN THE を定義する 私たちのボット、そして議論 この高い賭け環境で仲裁を成功して安全に実行するために必要なもの。 mathematical models underlying AMM pricing algorithms for opportunity detection and optimal price entry architectural components critical strategies The DeFi Landscape: AMMs, Liquidity, and Arbitration Opportunities(デフィの風景:AMM、流動性、仲裁の機会) 私たちの紹介で説明された「ダーク・フォース」は、敵対的な環境だけでなく、新しい金融パラダイムに基づいて構築された活気のある生態系です:分散型金融(DeFi)。その核心として、DeFiはブロックチェーンネットワーク上で伝統的な金融サービスを再構築することを目指し、自ら実行するスマート・コントラクトの使用を通じて仲介者の必要性を排除します。 自動化されたマーケットメーカー(AMMs):分散型交換の背骨 伝統的な取引所はオーダーブックに依存し、買い手と売り手はオファーを提出し、中央のマッチングエンジンは取引を容易にします。 DeFiは、自動市場メーカー(AMM)という根本的に異なるモデルを導入します。買い手と売り手を直接マッチする代わりに、AMMは2つ以上のトークンの準備を保有するスマート契約である流動性ポールを活用します。 AMMプール内の資産の価格は、アルゴリズム的にAによって決定されます。 , pioneered by Uniswap : constant product formula ここでは、x と y は流動性ポールの 2 つのトークンの量を表し、k は常数です。ユーザーが 1 つのトークンを別のトークンに取引すると、ポール内の x と y の量は変化しますが、彼らの製品 k は常に保持しなければなりません。このメカニズムはダイナミックに価格を調整します:トークンの A をより多く購入すると、ポール内のその量が減少し、トークン B に比べて価格を増加させます。 , 取引のための利用可能な価格ポイントを規定する。 bonding curve このモデルから、スワップからの出力金額(dy)を、入力金額(dx)と2つのトークン(xとy)のプレスワップ予備を考慮して、決定的に計算することができる。 Key characteristics of AMMs: 常に流動性:オーダーブックが薄くなるとは異なり、AMMはポールにトークンがある限り常に流動性を提供します。 許可なし:誰でも、承認を必要とせずに流動性提供者になるか、AMMで取引することができます。 価格発見:価格は、プール内の資産の比率によって決定され、各取引で調整されます。 Slippage: 大規模な取引は、プール内の価格を大幅に移動させることができ、スリッパージュと呼ばれる現象につながり、実行された価格は引用された価格よりも悪い。 たとえば、Uniswap V3は「集中流動性」(CLAMM)を導入し、LPが特定の価格範囲内で資本を割り当てることを可能にしました。これは、資本効率を大幅に改善しましたが、LPの複雑性も増加しましたし、したがって、さまざまな範囲で流動性を追跡する必要がある仲裁者も増加しました。 従来の製品公式(Uniswap V2 スタイルのプールのように)を使用して、より複雑なモデルに対処する前に基本的な理解を提供します。 we will primarily focus on AMMs The Essence of Arbitrage in DeFi 仲裁は、その最も純粋な形で、その価格の格差から利益を得るために、異なる市場で資産を同時に購入し販売することを意味します。DeFiでは、これは、異なるAMMポール間、またはAMMと中央取引所(CEX)間の価格格差を悪用することを意味します。同じトークンペアのためのDeFiの固有の許可のない性質と、さまざまなプロトコルにわたる分散された流動性は、これらの機会のための肥沃な土壌を作成します。この生じる金融空間における高い波動性と規制の欠如は、しばしば、仲裁者の生命の血液である重大な価格偏差につながります。 DeFiにおける仲裁の機会の種類 たとえば、1 ETH が 2000 DAI を Uniswap A で取引するが、1 ETH が 2010 DAI を Uniswap B で取引する場合、仲裁人は Uniswap A で ETH を DAI で購入し、すぐにその ETH を Uniswap B で DAI に売り、10 DAI の差をポケットにします(ガス料金とスリッパージャーを減らす)。 Triangular Arbitration (Multi-Leg):このタイプの仲裁は、同じ取引所(または複数の取引所)内の3つ以上の資産を含み、収益性の高いサイクルを形成します。たとえば、仲裁者はToken Aから始まり、Token Bに交換し、Token CにToken Bを交換し、最後にToken CがToken Aに戻り、AのToken Aをより多く持って終わります。Uniswapの共通例は、WETH -> DAI -> USDC -> WETHです。 フラッシュローン仲裁:DeFiの強力でユニークな側面で、フラッシュローンは、ユーザーが非保証資産を貸し出し、それらを一連の取引(仲裁のように)のために使用し、ローンを返済することを可能にします - 一つのブロックチェーン取引内ですべてです。 すべての操作のシーケンス(貸し出し、取引、返済)がこの単一の取引内で成功して完了できない場合、全体の取引は、それが決して起こらなかったかのように返されます。 これは、重要な前払い資本の必要性を排除し、大規模な仲裁のための入力の障壁を大幅に低下させますが、それはまた、すべての仲裁戦略が一つの原子操作内で慎重に編成されなければならないことを意味します。 私 The Race for Profit: Challenges and Competition(収益のためのレース:課題と競争) DeFiの風景は非常に効率的な市場です。価格の差異は、複雑なボットによって取される前に、しばしばミリ秒間しか存在しません。この激しい競争は、あらゆる野心的な仲裁者にとっていくつかの重要な課題を提示します。 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. Gas Fees: 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. Slippage: 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. Latency: 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, , 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. Frontrunning and MEV: our implementation will primarily operate on Base 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. Complexity of AMMs: 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. 建築設計: Arbitrage Bot Infrastructureの構築 DeFiの「Dark Forest」で収益性の高い仲裁ボットを構築するには、速度、信頼性、精度を優先するアーキテクチャが必要です。毎ミリ秒が重要であり、リアルタイムのデータを処理し、機会を特定し、取引を迅速に実行する能力が最重要です。 Goは、その例外的なパフォーマンス、強力な同期原理(goroutines and channels)、およびネットワークプログラミングと低レベルのシステム相互作用のための強力なエコシステムのために、主要な開発言語として選ばれました これらの機能は、ブロックチェーンデータの高流量とリアルタイム仲裁システムにおける並行処理の必要性に対処するために重要です。 主なEthereumクライアント go-ethereum The bot's architecture is structured as an いくつかの独立したサービス(モジュール)で構成されており、それぞれ並行プロセス(goroutines)で実行されています。これらのサービスは、Goチャンネルを通じてメッセージを送信することによって非同期的にコミュニケーションを起こし、ゆるやかに接続され、高度に反応する設計を確保します。 event-driven system システム構造全般 仲裁ボットのインフラストラクチャは、ブロックチェーンからデータが流れ、処理され、分析され、収益性のある取引の実行で頂点を迎えるパイプラインとして視覚化することができます。 Responsible for real-time ingestion of blockchain events data. Blockchain Data Reader Service: Maintains an in-memory representation of the DeFi market and identifies arbitrage paths. Market Graph Service: Evaluates detected opportunities for profitability and prepares trade instructions. Arbitrage Strategy Service: Constructs and dispatches blockchain transactions. Transaction Builder Service: A post-execution checker that enhances security and maintains market integrity by identifying and blacklisting malicious pools. Honeywall Service: 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. Blockchain Data Reader Service: The Eyes and Ears of Our Bot in the Data Stream(ブロックチェーンデータリーダーサービス:データストリームにおけるボットの目と耳) このサービスは、ブロックチェーンを通じて流れる原始的、リアルタイムのデータとボットの主要なインターフェイスとして機能します。Dark Forestでは、情報は通貨であり、それを迅速かつ正確に摂取する私たちの能力は最重要です。 それが私たちの仲裁の決定エンジンを養うでしょう。 extract crucial financial data points Connection and Data Ingestion: The Reader connects to a blockchain node via WebSockets. This persistent, bi-directional connection allows for immediate reception of new block headers and, more importantly, event logs issued by smart contracts. The service is configured to specifically listen for Swap, Mint, Burn, and Sync events from Decentralized Exchange (DEX) smart contracts. These events are crucial as they indicate changes in the reserves of liquidity pools, directly impacting token prices. このサービスは、分散型取引(DEX)スマートコントラクトからのSWAP、Mint、Burn、およびSyncイベントを特定に聴くように構成されています。 新しいブロックヘッダー: 新しいブロックヘッダーにサブスクリプションすることにより、各ブロックは、ブロックチェーンの現在の現実の確認されたスナップショットを表し、新しい取引、バランスを更新し、新しい流動性プールの状態を含む。 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: 効率を最適化し、過剰なチェーン通話を減らすために、Reader は、この目的のために特別に書かれたカスタムスマートコントラクトを使用します。 この契約は、データを返す前に集計として機能し、単一の最適化された呼び出しを提供して、複数の流動性カップルのための予備およびその他の集計情報を取得します。このカスタムコントラクトの主要な機能は、潜在的に有害または無益なプールに対する防御のファーストラインとして機能します。 コアの論理は checkPair メソッドにあり、これはトークンの安全性を評価し、合計データを返します。 // 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; } } イベント主導のコミュニケーション:これらのイベントを受け取って処理すると、Reader はデータを正常化し、市場グラフサービスに Go チャンネルを通じてメッセージとして更新(特定のプールの新しいバックアップ値など)を送信します。 Market Graph Service:Mapping the DeFi Market(デフィ市場のマッピング) Market Graph Service は、DeFi 市場のリアルタイム、メモリ内表示を維持する中央情報ユニットです。 どこで: directed graph ノード:個々の暗号通貨を表す(例えば、WETH、USDC、DAI)。 Edges: Represent liquidity pools on various DEXes (e.g., Uniswap V2 ETH/DAI pool, SushiSwap USDC/WETH pool). Each edge is associated with the current exchange rate (implied by the reserves) for the pair of tokens it connects. 各エンドは、接続するトークンの両方の現在の為替レート(準備によって意味される)と関連しています。 Data Structure and Updates: This service receives updates from the Blockchain Data Reader Service via channels. Upon receiving new reserve data for a pool, it updates the corresponding edge in the chart. It also handles the addition of new token pairs or DEXes as they are discovered. このサービスは、プールの新しいバックアップデータを受け取ると、グラフの関連するエッジを更新します。 BigInt による精度:トークン金額や為替レートに関連するすべての計算は Go の数学/ビッグパッケージ (BigInt または BigFloat) を使用します。これは任意の精度を維持し、チャンスを逃すことや利益の計算を間違える可能性のある浮点不正確性を防ぐために不可欠です。 Arbitrage Path Detection: Bellman-Ford Algorithm: このサービスの中心にあるFindArbitrage機能は、特にBellman-Fordのグラフ横断アルゴリズムを使用します。このアルゴリズムは、グラフ内でネガティブなサイクルを見つけるユニークな能力を持っており、これは私たちの市場モデル(ロガリズム為替レートがエッジ重量として使用される)の仲裁機会に正確に匹敵するものです。 最も効率的なコースを見つけることに焦点を当てている他の多くのグラフ理論アルゴリズムとは異なり、Bellman-Fordのネガティブなサイクルを検出する能力は、デフィと量的な金融アプリケーションの両方で非常に効率的です。 仲裁戦略サービス:利益の識別と最適化 Subscribe to the updated events from the 仲裁戦略サービスは、新たに検出された仲裁経路の市場グラフを継続的に監視しています。 Market Graph Service Opportunity Evaluation: グラフが更新されるたびに、またはFindArbitrageによって潜在的な仲裁経路が特定されるたびに、このサービスはアクションに浮上します。 最適な入力金額の計算(Convex Optimization):重要なステップは、仲裁順序のための最適な入力金額(dx)を決定することである。これは非トリビアな問題であるため、収益性は、入力金額の非線形の機能であり、『Uniswap市場の分析』の論文で示されています。これは、複数のスワップのスライプと料金によって影響されます。サービスは、Gonum/optimizeパッケージを使用して、この問題をコンベックス最適化の問題として解決します。 スワップのシミュレーション:取引を行う前に、サービスは、検出された仲裁パス内のすべてのスワップのシミュレート実行を行い、常時製品の公式と計算された最適な入力金額を使用します。このシミュレーション中に、各中間スワップステップのための最小出力金額も設定されます。これにより、予期せぬ低い実際の出力(例えば、突然の価格変動やチェーン上の高いスライプ)の場合、取引は無利潤または損失の取引に進むのではなく、最小のガス損失で返還されます。 すべての手数料:DEX取引手数料を含む(例えば、Uniswap V2の0.3%)。 Slippage: 順序内の各取引の価格影響を正確にモデリングします。 ガスコスト:連鎖(ベース)および現在のネットワーク条件を考慮し、取引全体に必要なガス料金の推定。 利益の上限:計算された純利益が最初の入力金額(または設定可能な上限)の少なくとも0.5%である場合にのみ、機会は実行可能とみなされます。 実行のための通知:有利な機会が基準を満たしている場合、仲裁戦略サービスは、スワップ(エッジ)の順序、最適な入力金額、およびその他の関連パラメータのすべての必要な詳細をまとめ、Goチャンネルを通じてトランザクションビルダーサービスに通知を送信します。 トランザクション ビルダー サービス: Swift Execution トランザクションビルダーサービスは、ブットの実行腕であり、ブロックチェーンに仲裁取引を迅速に構築し、提出するというタスクがあります。 取引構築:仲裁戦略サービスから機会を受け取った後、このサービスは直ちに原子ブロックチェーン取引の構築を開始します。 Smart Contract Interaction (Atomic Swaps): このサービスは、単一の原子取引内のすべての仲裁操作(複数のスワップ)を実行するために特別に設計されたカスタムスマート契約と相互作用する。 以下は、フラッシュローンなしで仲裁執行を処理するSolidity機能で、所有者(ボット)が最初の金額を資金調達する必要がありますIn: 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; } Flash Loan Integration: 仲裁のための最適な金額がフラッシュローンを必要とする場合、ビルダーは、AaveのFlashLoanSimpleインターフェイスを介してこの原子操作を容易にするカスタム契約を使用して、単一の、不可分な取引にフラッシュローンの論理(貸し出し→スワップを実行する→返済)を統合します。 以下は、Aave Poolが呼び出し、貸出された資金を使用して仲裁の論理を含む Solidity contract function executeOperation (part of a larger FlashLoanReceiver contract)です。 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; } Gas Estimation and Price: Dynamically estimates the required gas for the transaction and sets an appropriate gas price (or priority fee on L2s like Base) to ensure timely inclusion in a block. 取引に必要なガスを動的に推定し、ブロックに適切なガス価格(またはベースのようなL2の優先料金)を設定します。 トランザクションディスパッチ:構築されると、署名されたトランザクションはベースブロックチェーンノードに送信されます。ベースの選択は戦略的です:Ethereum L1とは異なり、ベースの現在のアーキテクチャは、伝統的な意味で公開的に見られるメプポールを特徴付けていません。これは、トランザクションはメプポールをスキャンするボットによって一般化されたフロントラリングを直接する可能性が低いことを意味します。マクシマル・エクストラクティブ・バリュー(MEV)はまだL2に存在しますが、その抽出のメカニズムはL1と異なります。 Asynchronous Feedback: 取引を送信した後、サービスは Honeywall サービスに通知を送信し、取引が開始され、モニタリングが必要であることをシグナルします。 Honeywall Service: 執行後の検証とセキュリティ Honeywall Service は、執行後の重要なチェックと、仲裁ボットの強力なセキュリティ レイヤーとして機能し、実行されたトランザクションの結果を検証し、悪意のある行為者から保護する役割を果たします。 トランザクション結果のモニタリング:トランザクションビルダーがトランザクションを配信した後、Honeywall Service はそのブロックに含まれることとその結果を監視します。 利益の記録:取引が成功し、利益を生み出す場合(シミュレーションから期待されるように)、利益の詳細はパフォーマンスの追跡と分析のために記録されます。 失敗分析:取引が失敗した場合、Honeywallは逆転の理由を分析します。 Honeypot / Scam Detection and Blacklisting: セキュリティの重要な機能は、欺瞞的な論理を実装する「honeypot」トークンまたはプールを識別する能力です(例えば、購入を許可するが販売を防止するか、販売に過剰な隠された税金を課す)。 外部プロバイダーの統合:それは、失敗した取引で使用されたカップルをクロス参照するために、外部プロバイダーまたは既知のハネドット契約のデータベースと統合し、潜在的な詐欺を特定します。 ダイナミックブラックリスト: 特定のカップルまたはプールが、予期せぬ高い税金のためにハネドットまたは問題として識別された場合、それはすぐにデータベースがサポートするブラックリストに追加されます。 Bloom Filter Integration: このブラックリストは、Bloomのフィルタメカニズムを介して効率的に管理されています. これにより、ブロックチェーンデータリーダーサービスは、新しく観察されたカップルをブラックリストに迅速にチェックする前に、それらの準備を回収したり、市場グラフに追加したりします. これは、ボットがリソースを無駄にしたり、将来的に既知の問題のカップルの取引を試みたりするのを防ぐために、積極的な防御として機能します。 建築デザインの結論 The modular, event-driven architecture implemented in Go, combined with specialized services for data ingestion, market modeling, opportunity optimization, rapid execution, and robust security, forms the backbone of our high-performance arbitrage bot. This design ensures that the system can react with unparalleled speed to fleeting market opportunities while also mitigating significant risks inherent to the DeFi “Dark Forest.” In the subsequent chapters, we will delve into the specific algorithms and implementation details of each of these services, starting with the intricate mathematics of opportunity detection. 4. Opportunity Detection and Optimal Execution: The Bot's Brain (オペレーション検出と最適な執行:ボットの脳) 仲裁ボットの本当の知恵は、絶えず変化する市場で収益性の高い機会を迅速かつ正確に特定し、最大収益のための実行を最適化する能力にあり、この章では、ボットの意思決定プロセスを支えるコアアルゴリズムと数学モデルに注目し、グラフとして市場をマッピングし、最適な取引サイズを正確に計算し、結果をシミュレートします。 グラフとしてのDeFi市場のモデリング アーキテクチャー概要で紹介したように、当社の Market Graph Service は DeFi 風景をターゲットグラフとして表します. In this model, individual tokens (e.g., WETH, DAI, USDC) serve as , while liquidity pools on various Decentralized Exchanges (DEXes) act as 各エッジの重さは、そのプールを通じて取引するコストを表します。 nodes edges To efficiently detect arbitrage opportunities, which manifest as profitable cycles, we transform the problem of finding a profitable sequence of trades into finding a この変換は、為替レートにロガリズム関数を適用することによって達成されます。 negative cycle サイクル検出のためのロガリズムの必要性 仲裁の背後にあるコアアイデアは、出発金額を一連の為替レートで倍増して、元の資産のより多くを得るようにすることである。 を貿易するために その後 のために そして、ついに Back to 私たちの最終的な金額は: TokenX TokenY TokenY TokenZ TokenZ TokenX グラフアルゴリズムで製品と作業することは困難です。複数の問題を添加的なものに変換するための計算財務における一般的なテクニックは、ロガリズムを適用することです。 今、収益性のあるサイクルのために、私たちは必要です。 つまり、 しかし、典型的な最短パスアルゴリズム(私たちが使用するBellman-Fordのような)は、最小限のパスを見つけるように設計されています。 of weights. To make a profitable cycle appear as a “negative cycle” in our graph, we simply negate the logarithmic rates: ln(最終) > ln(A) ln(RateX→Y) + ln(RateY→Z) + ln(RateZ→X) > 0 サム ln(RateX→Y) + ln(RateY→Z) + ln(RateZ→X) > 0 この変換により、ネガティブな値(すなわち、ネガティブなサイクル)を生み出す負の重量の合計は、有利な仲裁の機会を直接示します。 正確さと対処 BigInt DeFiのトークンの数は、小さな割合(たとえば、18桁のERC20トークン)から、非常に大きな数(たとえば、stablecoins)まで大きく異なります。この大きさの極度の異質性は、最大18桁の重要な数字まで広がり、標準の浮動点数値を精度の誤りに非常に敏感にします。 これを克服するために、当社のマーケットグラフサービス、および実際にボット内のトークン金額と為替レートを含むすべての計算は、Goの機能を利用します。 パッケージ、具体的に 整数算法および 必要に応じてフロントポイントの操作を行うため、 任意の精度を提供し、適用 2位 または 価値観は慎重な取り扱いを必要とし、標準として ネイティブで動作する機能 任意の精度のロガリズムを有するカスタマイズされた実装または外部ライブラリは、ここで不可欠です。 math/big BigInt BigFloat BigFloat log BigInt BigFloat math.Log float64 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) } ベルマン・フォードアルゴリズム(Bellman-Ford Algorithm) デフィ市場がロガリズム負のエッジ重量を有するグラフとして正確にモデル化されると、仲裁の機会を見つけるという課題は、識別に限定されます。 このグラフの中で、私たちは、そのために、 . negative cycles Bellman-Ford algorithm リチャード・ベルマン(Richard Bellman)とレスター・フォード(Lester Ford Jr.)にちなんで名付けられたベルマン・フォード(Bellman-Ford)は、ネガティブ・エッジ・ワイヤー(negative edge weights)を持つグラフを処理できる多様な最短コースアルゴリズムです。ネガティブ・サイクルの存在で失敗するディエクストラ(Dijkstra)のアルゴリズムとは異なり、ベルマン・フォード(Bellman-Ford)は、これらを検出するために特別に設計されています。その歴史的意義は、理論的なコンピュータサイエンスを超え、ネットワークルーティング(異なるコストで最も安いコースを見つけるのに役立つ)を含む様々な分野 アルゴリズムはエッジをリラックスさせ、一つのソースからすべてのノードへのより短い道を徐々に発見することにより動作します。 もし、 V −1 イテレーションの後(どこで V は頂点の数である)では、追加の N 番のイテレーションがまだ「リラックス」できる道を見つけることができ(すなわち、より短い道が見つかる)、それは負のサイクルの存在を示します。 この属性は私たちの使用ケースに最適です:負のサイクルは、純利益をもたらす取引の連続を意味し、正確に仲裁ボットが求めているものです。 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 } 最適な入力金額の計算:利益の最大化 ネガティブなサイクル(仲裁の機会)が特定されると、次の重要なステップは、 (dx) 順序の最初の取引の場合 これは任意ではありません; 仲裁の機会の収益性は、AMM スワップに関連する固有のスライプおよび手数料のために、取引サイズの非線形の機能です。 optimal input amount 「Uniswap市場の分析」で詳細に述べたように、恒久的な製品の公式は固有のところ、入力と出力の金額の関係における突出性を意味します。 具体的には、取引のサイズが大きくなるにつれて、効果的な為替レートはプールの不変性によって悪化します。 利益の最大化の問題は、A 仲裁経路におけるNスワップの連続の場合、最終出力金額(したがって利益)は、初期入力金額(dx)の関数として表現することができるが、複数の足の仲裁のための正確な分析ソリューションは、特に異なる手数料構造と異なるAMMのスライプ曲線で複雑であるが、利益マイナスコスト(ガスを含む)を表す関数は一般的に形である。 convex optimization problem 当社の仲裁戦略サービスは、Goの最適化ソリューターを採用することによってこれを解決します。 このソーラーは、純利益(スワップからの利益マイナス推定ガス料金およびすべてのフラッシュローンプレミアム)を表す機能を採用し、この値を最大化する入力金額を見つける。 公式 仲裁経路の各ステップに対して、各ステップにおける中間予備金、手数料、およびスライプを考慮すること。 gonum/optimize amountOut dy = (x + dx) / (dx⋅ y) 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 } スワップのシミュレーションと収益性評価 Before any transaction is dispatched, the Arbitrage Strategy Service performs a meticulous このステップは、リアルタイムの市場条件と提案された取引の正確なパラメータを考慮して、実際の収益性を検証するために重要です。 simulated execution このシミュレーションは、関連する流動性ポールの現在の予備と計算された最適な入力金額を用いており、複数の足路の各ステップに対して、特定のAMM式(例えば、Uniswap V2のようなポールの常時製品式)を適用して、予想される出力を計算します。 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 } 重要なのは、シミュレーションも組み込むことです。 checks for each intermediate step. These 値は、シミュレートされた期待される出力から得られ、実際のチェーン取引のパラメータとして設定される場合、ネットワークの遅延、フロントランニング、または予想外の市場条件により、実際のチェーン上のスワップの収益が指定された値より低い場合 このメカニズムは、ボットが無益なトランザクションを完了するのを防ぎ、損失を逆転したトランザクションに費やしたガスに限ります。 minimum output amount (minOut) minOut minOut ただし、最終的な純利益は、すべての手数料、スライプ、ガスコスト、およびフラッシュローンプレミアムの後で、事前定義された額を超える場合に限ります。 (たとえば、初期入力金額の0.5%)は、実行のためにトランザクションビルダーサービスに転送され、実行可能とみなされる機会です。 profit threshold トランザクションエンジニアリング:闇の森でのスピード執行 収益性のある仲裁の機会を特定することは、戦いの半分にすぎないが、もう一つの、おそらくより重要な半分は、比類のないスピードと信頼性で取引を実行する能力にある。DeFiの超競争力のある「ダーク・フォース」では、機会が飛び越え、複雑なボットが毎ミリ秒の生活を送っているところで、トランザクションエンジニアリングは芸術形式になる。 明るく、安全な実行を確保するために設計されています。 Transaction Builder Service The Imperative of Speed(スピードの必須) 分散型取引所における仲裁機会の収益性ウィンドウは、しばしばミリ秒で測定されます。価格の差異は、多くの自動化されたシステムによって迅速に検出され、利用され、新しいブロックに収益性のある取引を最初に含めるために激しい競争を起こします。いかなる遅延も、競合相手がその機会を奪われ、失敗した取引と無駄なガス料金につながります。したがって、トランザクションビルダーサービスにおけるすべての設計決定は、トランザクション構築からネットワーク提出まで、あらゆる段階で遅延を最小化することを目的としています。 In-Memory Optimization for Instantaneous Transaction Building (インメモリの最適化) To achieve the necessary velocity, our system prioritizes having all essential transaction components readily available in memory, eliminating costly I/O operations or on-chain calls during the critical transaction building phase. Pre-Parted and Packed ABIs: Smart Contract Application Binary Interfaces (ABIs) は、契約とどのように相互作用するかを定義します。 ABI 定義を解析し、各取引のフライト上の機能呼び出しを暗号化する代わりに、当社のシステムは、必要な ABI データ構造と機能セレクターをサウルバイトの配列にプリパッケージし、パッケージします。これらの共通の契約の相互作用(例えば、swapExactTokensForTokensForTokens、flashLoanSimple、transferFrom)のための事前計算されたバイトシーケンスは、メモリに保存されます。仲裁の機会が特定されるとき、Transaction Builder は単にこれらのプレパッケージ トランザクションフィールド用のキャッシュオンチェーンデータ: トランザクションメタデータに対する過剰なチェーン呼び出しを避けるために、ボット内の専用ユーティリティ構造は、メモリに重要で頻繁に更新される値を保持します。 アカウント ノンセ: ノンセ(アドレスから送信されたトランザクションの数)は、再生攻撃を防止し、トランザクションの注文を確保するために重要です。 最適なガスパラメータ: 各取引に対してガス価格(または EIP-1559 チェーン上の基準料金/優先料金)をネットワークに問い合わせる代わりに、ボットは定期的に最適なガスパラメータを取得します。 署名者情報:ボットの財布のプライベートキーと関連する署名者オブジェクト(暗号化署名取引に使用)は、初期化時にメモリにロードされます。 これらの重要なコンポーネントを記憶に保つことで、トランザクションビルダーサービスは、すぐに送信する準備ができ、わずかマイクロ秒で完全なブロックチェーン取引を構築し、署名することができます。 ダイナミックスマート契約選択:Flash Loans vs. Direct Swaps 仲裁戦略サービスは、最適化された仲裁パスと計算された最適な入力金額をトランザクションビルダーに渡します。 それが事前に定義された資本の限界を超えていても(あるいは、戦略が明示的にそれを要求している場合)、トランザクション ビルダーは、実行するための2つの主要なスマート コントラクトの間で動的に選択します。 amountIn Direct Swap Execution Contract: ボットの所有資本によって直接資金調達できる機会のために、ビルダーは、カスタマイズされたマルチスワッププロキシ契約で executeArb 関数(または類似)を使用します。第3章で示されているように、この契約はボットの財布から入力トークンを取って、単一の原子取引内のスワップの全セクションを実行します。 Flash Loan Integrated Contract: 仲裁のための計算された最適な金額がボットの利用可能な資本よりもはるかに大きい場合、ビルダーは、フラッシュローンを開始し管理するために設計された別々のカスタムスマート契約をターゲットにします。 この契約のスタートArbitrage機能(第3章で詳細に述べたように)は、Aaveのようなプロトコルからフラッシュローンを要求し、それから契約の実行オペレーション機能を呼び戻します。 このダイナミックな選択は、発見されたそれぞれの機会の特性に基づいて、効率的な資本配分と最適な戦略実行を保証します。 Mempool Dynamics: Navigating Ethereum L1 vs. Layer 2 Chains(メンポール・ダイナミクス) 仲裁執行の重要な側面は、ブロックチェーンの取引拡散メカニズムを理解すること、とりわけ . 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 (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 the original, thereby stealing the profit. This competitive landscape makes direct arbitrage on L1 highly challenging without leveraging specialized MEV relays. Ethereum L1 Mempool: generalized frontrunning bots before Our bot strategically operates on , an EVM-compatible Layer 2 blockchain. The architecture of many L2s, including Base, fundamentally alters the traditional L1 mempool dynamic. Instead, transactions are typically sent directly to a centralized sequencer or a private mempool before being batched and committed to the L1. Layer 2 (L2) Chains and Reduced Mempool Visibility (e.g., Base): Base Base does not currently expose a publicly visible mempool in the same manner as Ethereum Layer 1. 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. ノードスピードとセキュリティ:信頼できる実行の基盤 ブロックチェーンノードへの接続は、すべてのデータとトランザクションの単一の入力と出力ポイントです。 高性能ノード接続:トランザクションビルダーサービスは、専用の高性能ノードプロバイダー(例えば、Alchemy、Infura、または自己ホストノード)に接続します。高速で低遅延性の接続は、トランザクションの署名とそのネットワークへの拡散の間の時間を最小限に抑えるために不可欠です。 ノードのセキュリティとインテリジェンス:接続されたノードのセキュリティは同様に重要です。信頼できるノードプロバイダーを使用するか、高度にセキュアな自己ホスティングノードを確保することは、中間攻撃やデータの妨害を防ぐために重要です。損なわれたノードはプライベートキーを漏らしたり、悪意のある取引を注入したり、データを操作したり、災害的な損失をもたらします。私たちのシステムのプライベートRPCエンドポイント(プロバイダーから利用可能な場合)とセキュアな通信チャネル(https for HTTP、wss for WebSockets)への依存は、このセキュリティ姿勢を強化します。 メモリー内のデータ構造やプレコンピューティングから戦略的チェーン選択や強力なノードインフラストラクチャまで、あらゆるレイヤーでスピードを精密に最適化することで、当社の仲裁ボットは、競争相手を凌駕し、DeFiの景観内で浮上する機会を安全に活用するように設計されています。 6.Dark Forest Navigation: Challenges, Ethics, and Future Prospects(闇の森を航行する:課題、倫理、未来の展望) DeFi「Dark Forest」における仲裁ボットの構築と運用は、分散型テクノロジーの力の証拠であるが、重要な課題と倫理的考慮事項も明らかにしている。 The Constant Battle Against Malicious Actors: The Role of Bloom(ブルームの役割) DeFiの許可のない性質を取り巻く初期の楽観主義は、残念ながら、悪意のある俳優の拡散によって緩和されました。 重要な最後の防衛線として役立つが、これらの悪役たちの発明性は絶えず進化する対処措置を必要としている。 Honeywall Service この防衛の重要な要素は、 . ブルームフィルターは、要素がセットのメンバーであるかどうかを迅速かつ効率的にテストできる確率データ構造です。 非常にスペース効率的ですが、「偽ポジティブ」の可能性が少ない(要素がセットにない場合に存在することを示す)が、決して「偽ネガティブ」ではありません。 私たちの文脈では、ブルームフィルターは、ブロックチェーンデータリーダーサービスから入力するイベントデータを事前フィルターするために使用されます。 それは、既知の悪意のあるまたは高税金の流動性のカップルのハッシュを含みます。 詳細な処理または予備回収の前に、ブルームフィルターに対する迅速なチェックは、既知の問題のカップルをすぐに排除し、計算資源と潜在的なリスクの無駄を防 Bloom filter 私たちの慣習で実施された洗練された事前チェックにもかかわらず、 スマートコントラクト(特に 税金を評価するためにラウンドトラップ・スワップをシミュレートする論理)で、いくつかの悪意のあるカップルはまだこれらの初期のオンチェーンの検証を回避することに成功しています。 関数(価格クエリに用いられる)は、見た目に正常な、低税率の出力を返します。しかし、真の「ハネイポット」の論理は実際の内部に深く埋め込まれています。 あるいはベース これらの機能は、売却業務に過大な隠された税金(例えば、99%)を課すか、販売を完全に制限し、効果的に資金を捕らえる可能性があります。 ArbHelperMap _checkTaxLimit getAmountsOut swapExactTokensForTokens transfer 私たちのテスト段階では、私たちはそのような詐欺的なカップルの重要な数に遭遇しました 私自身は、最初に成功したいくつかのカップルのアドレスを収集しました。 この db ファイルは、プロジェクトの GitHub リポジトリで公開され、これらの落とし穴を避けるためのコミュニティのリソースとして機能します。この継続的なネコとマウスゲームは、継続的な監視、迅速なブラックリストの必要性を強調し、複数のレイヤーの防衛戦略を提供します。 getAmountsOut 倫理的影響と闇の森の影 「ダーク・フォースト」の類似性は、ボット間の競争だけでなく、デフィーのより広範な倫理的環境にも適しているが、市場の健康と価格の発見に不可欠な仲裁の効率性は、厳しい現実を伴う:仲裁者によって生成された利益は、しばしば、より複雑な市場参加者から抽出された価値を表している。 The pervasive culture of 基本的なブロックチェーンメカニズムや金融ツールの一般的な理解の欠如とともに、多くの小売ユーザーがこの環境で簡単に獲物を獲ることができます。 FOMO (Fear Of Missing Out) このダイナミクスは、高度なツールを持つ人々にとって経済的に論理的ですが、分散型テクノロジーの評判に影を落とします。この話は「財務的権限」から「強盗行為」へと急速に変化し、そうでないと膨大な約束を保つ空間への信頼を侵害します。 DeFiは、その核心として、金融を民主化し、許可のないアクセスを提供し、透明性を提供することを目指しています。しかし、MEVの複雑な性質と詐欺の普及は、誤ってこれらの理想を破壊し、テクノロジーの熟練者だけが真に安全に航海できる2レベルのシステムを作り出すことができます。建設者として、私たちはこれらの倫理的次元を認識し、より高いユーザー教育、 タイトル: Still Navigating the Dark Forest DeFiの内在する複雑さと持続的な課題にもかかわらず、この仲裁ボットのエンジニアリングの旅は、実践的な実施に適合する理論的原則の素晴らしい検証でした。 複数の仲裁の機会を検出し、実行することができる。 speed, precision, and data-driven insights 当初、「ダーク・フォース」の共通の期待は、仲裁価値の大半がすぐに大規模で資源豊富なプレイヤーによって、自己ホスティングノードを活用し、ブロックプロデューサーへの直接のアクセスを活用することにあったが、我々のテストと成功した取引は、より小さい、よく設計されたボットがこれらの短期的な機会を一貫して発見し、利用することが可能であることを示した。 古いAMMモデルの有益な仲裁は、Uniswap V2(主に恒久的な製品プールに依存する)のような古いAMMモデルでは、ガスコストの拡大と競争の激化により長期的に維持するのに困難であるが、「ダーク・フォース」は進化し続けている。Uniswap V3の集中流動性AMM(CLAMM)のような新しい実施は、より洗練されたモデリングを必要とする新しい仲裁ベクターを導入するが、資本効率の向上により高収益を生み出すことが多い。さらに、クロスチェーン仲裁、ブリッジの活用、およびブロックチェーン間通信プロトコルは、さまざまなブロックチェーンネットワーク間の付加価値価格の相違から拡大する だから、私はまだ貧乏ですが、私は素晴らしい森の航海家になったと言えるでしょう。 My compass is sharper, my map more detailed, and I understand the whispers of the canopy. プロジェクトリポジトリ 私たちが議論した「」の背後にある実用的な実装と非常に実際のデータに深く浸透したい人々のために、私たちのコードベースの衛生化されたバージョンと、既知の悪意のあるトークンカップルで埋め込まれたデータベースが私のサイトで利用できます。 これらの85の特定のカップルは、数的に小さいものの、無謀なボットを無益な取引に誘惑しようとしているため、相対的に大きな取引量を生成します。 GitHub リポジトリ GitHub リポジトリ 参照 Dan Robinson, Georgios Konstantopoulos 「Ethereum is a Dark Forest」 パラダイム Guillermo Angeris, Hsien-Tang Kao, Rei Chiang, Charlie Noyes, and Tarun Chitra. 「Uniswap市場の分析」Cryptoeconomic Systems。 Claudio Gebbia. “Analysis and Implementation of Arbitration Bots in Centralized and Decentralized Finance”, チューリッヒ大学。 Y. Zhang, Z. Li, T. Yan, Q. Liu, N. Vallarano and C. J. Tessone, “Profit Maximization in Arbitrage Loops”. archiv. 「仲裁ループにおける利益の最大化」