1. Johdanto -Pimeässä metsässä
1. Johdanto -Myöhään yöllä, Dan Robinson, tutkija sijoitusyhtiö Paradigm, näki hätänumero Uniswap Discord kanava.Kaksitoinen käyttäjä, mutta Uniswap-sopimukseen itse, jossa ne näyttivät olevan peruuttamattomasti menetettyjä.
Robinson näki kuitenkin toivon hehkun. hän tajusi, että kuka tahansa voi laukaistaburn
Toiminta sopimuksessa, julkinen käsky, joka pakottaisi sopimuksen vapauttamaan jumissa olevat tokenit henkilölle, joka soitti sen.
Tunnistamalla mahdollisuuden olla valkoinen hattu sankari, Robinson valmisteli pelastustoimintaa. Mutta hän tiesi, että hän ei ollut yksin. Ethereum mempool - julkinen odotushuone odottavat tapahtumia - on metsästysmaata hienostuneita robotteja tunnetaan nimellä "yleinen frontrunners."Nämä saalistajat jatkuvasti skannata mitään kannattavaa toimintaa, välittömästi kopioi sen, ja korvaa alkuperäisen osoitteen omalla varastaa palkinnon.
Voidakseen ohittaa heidät, Robinson keksi älykkään kahden osan liiketoimen, toivoen, että molemmat osat kaivettiin samanaikaisesti, jättäen ikkunan hälytykseen. Se ei toiminut. Silloin kun hänen ensimmäinen liiketoimensa ilmestyi, botti havaitsi sen, kopioi koko strategian ja ryösti 12 000 dollaria ennen kuin Robinsonin toinen liiketoimi voitiin jopa vahvistaa.
Nyt kuuluisassa esseessä tapahtumasta Robinson antoi tämän vihamielisen, näkymättömän ekosysteemin nimen.Ethereum is a Dark Forest.
Tässä artikkelissa tutustumme järjestelmän suunnitteluun, joka pystyy lukemaan reaaliaikaisia toimintoja ja tietoja lohkoketjun transaktioista, tavoitteena suorittaa välimiesmenettely.mathematical models underlying AMM pricingja syöksy sisäänalgorithms for opportunity detection and optimal price entryMäärittele searchitectural componentsMeidän bändimme ja keskustelemmecritical strategiesTarvitaan, että välimiesmenettely toteutetaan menestyksekkäästi ja turvallisesti tässä korkeatasoisessa ympäristössä.
2. DeFi Landscape: AMMs, likviditeetti ja välimiesmenettely mahdollisuuksia
Johdannossamme kuvattu "Pimeä metsä" ei ole vain vihamielinen ympäristö; se on elinvoimainen ekosysteemi, joka on rakennettu uudelle taloudelliselle paradigmalle: hajautetulle rahoitukselle (DeFi). Sen ytimessä DeFi pyrkii luomaan perinteisiä rahoituspalveluja lohkoketjuverkostoille, eliminoimalla välittäjien tarve käyttämällä itsenäisesti täytäntöönpanoa älykkäitä sopimuksia.
Automated Market Makers (AMMs): hajautetun vaihdon selkäranka
Perinteiset pörssit luottavat tilauskirjoihin, joissa ostajat ja myyjät tekevät tarjouksia ja kysyvät, ja keskitetty vastaava moottori helpottaa kauppoja. DeFi esittelee radikaalisti erilaisen mallin: Automated Market Maker (AMM). Sen sijaan, että vastaavat suoraan ostajia ja myyjiä, AMM: t hyödyntävät likviditeettipoolia - älykkäitä sopimuksia, joissa on kahden tai useamman tokenin varantoja - helpottaakseen kauppoja. Käyttäjät, jotka tunnetaan likviditeetin tarjoajina (LPs), tallettavat vastaavia arvoja tokenipareista näihin pulloihin, ansaitsevat osan kaupankäyntimaksuista vastineeksi.
AMM-poolin sisällä olevien varojen hinta määritetään algoritmisesti aconstant product formula, jonka on kehittänyt Uniswap:
Tässä x ja y edustavat likviditeettipoolin kahden tokenin määrää, ja k on pysyvä. Kun käyttäjä kauppaa yhden tokenin toiselle, poolin x- ja y-määrät muuttuvat, mutta niiden tuotteen k on pysyttävä jatkuvana. Tämä mekanismi säätää hintaa dynaamisesti: ostaa enemmän tokenia A vähentää sen määrää poolissa, mikä lisää sen hintaa suhteessa tokeniin B ja päinvastoin.bonding curve, joka määrittelee kaupankäynnin käytettävissä olevat hintapisteet.
Tästä mallista on mahdollista deterministisesti laskea swapin tuotantomäärä (dy), kun otetaan huomioon kahden tokenin (x ja y) syöttömäärä (dx) ja pre-swap-varannot:
Key characteristics of AMMs:
- Always-on Liquidity: Toisin kuin tilauskirjat, jotka voivat muuttua ohuiksi, AMM: t tarjoavat aina likviditeettiä niin kauan kuin poolissa on tokeneja.
- Luvaton: Kuka tahansa voi tulla likviditeetin tarjoajaksi tai käydä kauppaa AMM: llä ilman hyväksyntää.
- Hintojen löytäminen: Hinnat määräytyvät poolin sisällä olevien varojen suhteen mukauttamalla kunkin kaupan kanssa.
- Slippage: Suuret kaupat voivat merkittävästi siirtää hintaa poolissa, mikä johtaa ilmiöön, joka tunnetaan nimellä slippage, jossa suoritettu hinta on huonompi kuin mainittu hinta.
Vaikka x⋅y=k-malli (jota usein kutsutaan nimellä Uniswap V2) loi perustan, AMM:t ovat kehittyneet. Uniswap V3, esimerkiksi, otti käyttöön ”konsentroidun likviditeetin” (CLAMM), jonka ansiosta LP:t voivat kohdistaa pääomansa tiettyjen hintaluokkien sisällä. Tämä paransi merkittävästi pääoman tehokkuutta, mutta myös lisäsi monimutkaisuutta LP:ille ja siten välimiesmenettelyille, joiden on seurattava likviditeettiä eri alueilla.we will primarily focus on AMMskäyttämällä jatkuvaa tuotekaavaa (kuten Uniswap V2-tyyppiset poolit), koska ne tarjoavat perustavanlaatuisen ymmärryksen ennen monimutkaisempien mallien käsittelyä.
The Essence of Arbitrage in DeFi
Välimiesmenettely puhtaimmassa muodossaan on varojen samanaikainen osto ja myynti eri markkinoilla voittamaan hintaeroa. DeFi: ssä tämä tarkoittaa eri AMM-poolien tai AMM: n ja keskitetyn pörssin (CEX) välisten hintaerojen hyödyntämistä samalle tokeniparille. DeFi: n luontainen luvaton luonne ja hajanainen likviditeetti eri protokollissa luovat hedelmällisen maaperän näille mahdollisuuksille. Tämän syntymän rahoitusalueen korkea volatiliteetti ja sääntelyn puute johtavat usein merkittäviin hintarajoituksiin, jotka ovat välimiesten elinvoima.
Välimiesmenettelyn mahdollisuudet DeFi: ssä
- Yksinkertainen välimiesmenettely (Two-Leg): Tämä on yksinkertaisin muoto, johon liittyy kaksi eri paikkaa. Esimerkiksi jos 1 ETH kauppaa 2000 DAI: lla Uniswap A: lla, mutta 1 ETH kauppaa 2010 DAI: lla Uniswap B: llä, välimies voi ostaa ETH: n Uniswap A: lla DAI: llä ja myydä välittömästi ETH: n DAI: lle Uniswap B: llä.
- Kolmiosainen välimiesmenettely (Multi-Leg): Tämäntyyppinen välimiesmenettely sisältää kolme tai useampia varoja samassa pörssissä (tai useissa pörsseissä) muodostaakseen kannattavan syklin. Esimerkiksi välimies voi aloittaa Token A:lla, vaihtaa sen Token B:lle, sitten Token B:lle Token C:lle ja lopulta Token C:lle takaisin Token A:lle, päättyen enemmän Token A:lla kuin he aloittivat. Yhteinen esimerkki Uniswapista voi olla: WETH -> DAI -> USDC -> WETH. Päätavoitteenamme on toteuttaa ja käyttää Multi-Leg-välimiesmenettelyä eri DEX AMM:ien välillä.
- Flash Loan Arbitrage: Voimakas ja ainutlaatuinen näkökohta DeFi, flash lainoja avulla käyttäjät voivat lainata vakuudettomia varoja, käyttää niitä sarjan liiketoimia (kuten välimiesmenettely), ja maksaa takaisin lainan - kaikki sisällä yhden blockchain transaktio. Jos koko sekvenssi toimintoja (lainaa, kauppa, maksaa) ei voida suorittaa onnistuneesti sisällä yksittäinen transaktio, koko transaktio palautetaan, ikään kuin se ei olisi koskaan tapahtunut. Tämä poistaa tarvetta merkittävä etukäteen pääomaa ja merkittävästi alentaa esteen pääsyn laajamittaista välimiesmenettelyä, mutta se tarkoittaa myös, että koko välimiesmenettely strategia on huolellisesti organisoitu yhden atomisen toiminnan. Me sisällytämme flash laina vaihtoehto
Kilpailu voiton puolesta: haasteet ja kilpailu
DeFi-maailma on erittäin tehokas markkinapaikka. Hintaerot ovat epävakaita, usein olemassa vain millisekuntia ennen kuin hienostuneet robotit hyödyntävät niitä.
-
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.
Arkkitehtuurisuunnittelu: Arbitration Botin infrastruktuurin rakentaminen
Hyödyllisen välimiesmenettelyrobotin rakentaminen DeFi:n ”Pimeässä metsässä” vaatii arkkitehtuuria, joka asettaa etusijalle nopeuden, luotettavuuden ja tarkkuuden. Jokainen millisekunti laskee, ja kyky käsitellä reaaliaikaisia tietoja, tunnistaa mahdollisuuksia ja suorittaa kauppoja nopeasti on ensiarvoisen tärkeää.
Go valittiin ensisijaiseksi kehityskieleksi sen poikkeuksellisen suorituskyvyn, vahvojen samanaikaisten primitiivien (goroutineja ja kanavia) ja vahvan ekosysteemin vuoksi verkko-ohjelmointiin ja matalan tason järjestelmien vuorovaikutukseen. Nämä ominaisuudet ovat kriittisiä blockchain-tietojen suuren läpäisyn käsittelemiseksi ja tarpeen rinnakkaiselle käsittelylle reaaliaikaisessa välimiesmenettelyjärjestelmässä.go-ethereum
Ethereum on ensisijainen asiakas.
Arkkitehtuuri on rakennettu niin, ettäevent-driven systemkoostuu useista itsenäisistä palveluista (moduuleista), joista kukin toimii rinnakkaisissa prosesseissa (goroutineissa). Nämä palvelut kommunikoivat epäsynkronisesti lähettämällä viestejä Go-kanavien kautta, mikä takaa löysästi kytketyn ja erittäin reagoivan suunnittelun.
Koko järjestelmän arkkitehtuuri
Välimiesrobotin infrastruktuuri voidaan visualisoida putkeksi, jossa data virtaa lohkoketjusta, käsitellään ja analysoidaan ja huipentuu kannattavien kauppojen suorittamiseen.
-
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.
Blockchain Data Reader -palvelu: Bottimme silmät ja korvat datavirrassa
Tämä palvelu toimii botin ensisijaisena käyttöliittymänä, jossa raaka, reaaliaikainen data virtaa lohkoketjun läpi. ”Pimeässä metsässä” tieto on valuutta, ja kykyämme nopeasti ja tarkasti niellä se on ensisijainen.extract crucial financial data pointsTämä ruokkii meidän päätöksenteko moottorimme.
- Liittäminen ja tietojen syöttäminen: Reader muodostaa yhteyden lohkoketjuun WebSocketsin kautta. Tämä pysyvä, kaksisuuntainen yhteys mahdollistaa uusien lohkokohtien välittömän vastaanoton ja mikä tärkeintä, älykkäiden sopimusten lähettämien tapahtumapäiväkirjojen. Palvelu on konfiguroitu kuuntelemaan erikseen hajautetun kaupan (DEX) älykkäiden sopimusten Swap-, Mint-, Burn- ja Sync-tapahtumia. Nämä tapahtumat ovat ratkaisevia, koska ne osoittavat muutoksia likviditeettipoolien varastoissa, jotka vaikuttavat suoraan tokenien hintoihin.
- Uudet lohkokohteet: Tilaamalla uudet lohkokohteet saamme välittömästi ilmoituksen tilan muutoksista. Jokainen uusi lohko edustaa vahvistettua valokuvaa lohkoketjun nykyisestä todellisuudesta, mukaan lukien uudet liiketoimet, päivitetyt saldot ja uudet likviditeetipohjan tilat. Tämä virta tarjoaa perustiedot markkinakaavioidemme säännöllisille päivityksille ja omien liiketoimien tulosten vahvistamiseksi.
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: Optimoidakseen tehokkuutta ja vähentääkseen ketjupuheluita Reader käyttää tähän tarkoitukseen erityisesti kirjoitettua mukautettua älykkäästä sopimusta. Tämä sopimus toimii aggregaattorina, joka tarjoaa yhden optimoidun puhelun varantojen ja muiden yhteenlaskettujen tietojen hankkimiseksi useille likviditeettiparille. Tämän räätälöidyn sopimuksen keskeinen toiminto on sen sisäänrakennettu ennakkotarkastus yhteisten huijausominaisuuksien tai liiallisten kaupankäyntimaksujen varalta poolissa ennen tietojen palauttamista. Tämä alustava suodatus vähentää merkittävästi riskiä vuorovaikutuksessa haitallisten sopimusten kanssa alaspäin toimimalla ensimmäisenä puolustus
- Ydinlogiikka on checkPair-menetelmässä, joka arvioi tokeniparien turvallisuuden ja palauttaa aggregoidut tiedot.
// 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;
}
}
- Tapahtumapohjainen viestintä: Näiden tapahtumien vastaanottamisen ja käsittelyn jälkeen Reader normalisoi tiedot ja lähettää päivityksiä (esim. tietyn joukon uudet varausarvot) viesteinä Go-kanavan kautta Market Graph -palveluun.
Market Graph Service: DeFi-markkinoiden kartoittaminen
Market Graph Service on keskeinen tiedusteluyksikkö, joka ylläpitää DeFi-markkinoiden reaaliaikaista muistikuvaa.directed graphMissä siis:
- Solmut: edustavat yksittäisiä kryptovaluuttoja (esim. WETH, USDC, DAI).
- Edges: edustavat likviditeettikeskuksia eri DEXeissä (esimerkiksi Uniswap V2 ETH/DAI -keskuksessa, SushiSwap USDC/WETH -keskuksessa).
- Tietorakenne ja päivitykset: Tämä palvelu vastaanottaa päivityksiä Blockchain Data Reader -palvelusta kanavien välityksellä. Kun vastaanotat uusia varantotietoja joukosta, se päivittää vastaavan reunan kaaviossa.
- Tarkkuus BigIntin kanssa: Kaikki laskelmat, joissa käytetään tokenimääriä ja valuuttakursseja, käyttävät Go: n matemaattista/suurta pakettia (BigInt tai BigFloat). Tämä on ratkaisevan tärkeää mielivaltaisen tarkkuuden ylläpitämiseksi, estämällä kelluva-pisteen epätarkkuuksia, jotka voisivat johtaa mahdollisuuksien menettämiseen tai virheellisiin voittojen laskelmiin.
- Arbitrage Path Detection: Bellman-Ford Algorithm: Tämän palvelun ytimessä on FindArbitrage-toiminto, joka käyttää graafin läpiviennin algoritmia, erityisesti Bellman-Ford. Tämä algoritmi kykenee yksilöllisesti löytämään negatiivisia syklejä kaaviossa, mikä on juuri se, mikä vastaa välimiesmenettelyä markkinoiden mallissa (jossa logaritmisia valuuttakursseja käytetään reuna-arvoina). Toisin kuin monet muut graafiteorian algoritmit, jotka keskittyvät tehokkaimman polun löytämiseen, Bellman-Fordin kyky havaita negatiivisia syklejä tekee siitä poikkeuksellisen tehokkaan sekä DeFi- että kvantitatiivisissa rahoitussovelluksissa, joissa etsitään voittoa syklisista eroista.
Arbitraatiostrategian palvelu: voittojen tunnistaminen ja optimointi
Ilmoittautuminen päivityksiin tapahtumistaMarket Graph ServiceArbitration Strategy Service seuraa jatkuvasti markkinoiden kaaviota äskettäin havaittujen välimiesmenettelyn polkuja.
- Mahdollisuuksien arviointi: Joka kerta, kun kaavio päivitetään tai FindArbitrage tunnistaa mahdollisen välimiesmenettelyn polun, tämä palvelu alkaa toimia.
- Optimaalinen syöttömäärän laskenta (Convex Optimization): Kriittinen vaihe on määrittää optimaalinen syöttömäärä (dx) arbitraasijärjestykselle. Tämä on ei-triviaalinen ongelma, koska kannattavuus on syöttömäärän ei-lineaarinen toiminto, kuten on osoitettu artikkelissa ”Uniswap-markkinoiden analyysi”. Se vaikuttaa liukumiseen ja maksuihin useiden swapien välillä. Palvelu ratkaisee tämän ongelmana käyttämällä Go: n gonum/optimize -pakettia. Tämä varmistaa, että valittu syöttömäärä maksimoi nettotuloksen kaikkien muuttujien kirjanpidon jälkeen.
- Swap-simulointi: Ennen liiketoimeen ryhtymistä palvelu suorittaa simuloidun suorittamisen kaikista tunnistetuissa välimiesmenettelytapahtumissa käyttämällä jatkuvaa tuotekaavaa ja laskettua optimaalista syöttömäärää.Tämän simuloinnin aikana vähimmäistuoton määrät asetetaan myös jokaiselle välivaiheelle.Tämä varmistaa, että jos todelliset tuotot ovat odottamattomasti alhaiset (esimerkiksi äkillisten hintojen vaihtelujen tai ketjun suuren liukumisen vuoksi), liiketoimi palautuu minimaalisella kaasun menetyksellä eikä jatketaan kannattamattomalla tai häviävällä kaupalla.
- Kaikki maksut: Sisältää DEX-kaupankäyntimaksut (esim. 0,3% Uniswap V2:lle).
- Slippage: Tarkasti mallinnetaan kunkin kaupan hintavaikutus sekvenssissä.
- Kaasukustannukset: Arvio kaasumaksuista, joita tarvitaan koko transaktiolle, ottaen huomioon ketjun (Base) ja nykyiset verkon olosuhteet.
- Voittojen kynnysarvo: Vain jos laskettu nettotulos on vähintään 0,5 prosenttia alkuperäisestä syöttömäärästä (tai konfiguroitava kynnysarvo), mahdollisuus katsotaan elinkelpoiseksi.
- Täytäntöönpanoa koskeva ilmoitus: Jos kannattava tilaisuus täyttää kriteerit, välimiesmenettelystrategiapalvelu kokoaa kaikki tarvittavat yksityiskohdat - järjestetty swap-järjestys (rajat), optimaalinen syöttömäärä ja muut asiaankuuluvat parametrit - ja lähettää ilmoituksen Go-kanavan kautta Transaction Builder -palveluun.
Transaction Builder Service: Nopea toimeenpano
Transaction Builder -palvelu on botin täytäntöönpanoväline, jonka tehtävänä on nopeasti rakentaa ja toimittaa välimiesmenettely blockchainille.
- Transaction Construction: Saatuaan mahdollisuuden Arbitrage Strategy Service, tämä palvelu välittömästi alkaa rakentaa atomic blockchain transaktio.
- Smart Contract Interaction (Atomic Swaps): Tämä palvelu on vuorovaikutuksessa räätälöidyn älykkään sopimuksen kanssa, joka on suunniteltu suorittamaan kaikki välimiesmenettelytoiminnot (monia vaihtoja) yhdellä atomioperaatiolla. Tämä sopimus käsittelee myös token-hyväksynnät samassa transaktiovirrassa.
- Tässä on Solidity-toiminto, joka käsittelee välimiesmenettelyn täytäntöönpanoa ilman flash-lainaa, joka vaatii omistajaa (bottia) rahoittamaan alkuperäisen summanIn:
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-lainan integrointi: Jos välimiesmenettelyn optimaalinen määrä edellyttää flash-lainaa, rakentaja integroi flash-lainan logiikan (lainaa → suorittaa swapit → maksaa) yhdeksi, jakamattomaksi tapahtumaksi käyttämällä räätälöityä sopimusta, joka helpottaa tätä atomitoimintaa Aaven FlashLoanSimple -liittymän kautta.
- Tässä on Solidity-sopimuksen toiminto toteuttaaoperaatio (osa suuremmasta FlashLoanReceiver -sopimuksesta), jonka Aave Pool kutsuu ja sisältää välimiesmenettelyn logiikan lainassa olevien varojen avulla:
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;
}
- Arviointi ja hinta: Arvioi dynaamisesti kaupan edellyttämän kaasun ja asettaa asianmukaisen kaasun hinnan (tai etusijamaksun L2:lle, kuten Base) varmistaakseen oikea-aikaisen sisällyttämisen lohkoon.
- Transaction Dispatch: Kun se on rakennettu, allekirjoitettu transaktio lähetetään Base-blockchain-solmuun. Base-valinta on strateginen: toisin kuin Ethereum L1, Base: n nykyisellä arkkitehtuurilla ei ole julkisesti näkyvää mempoolia perinteisessä merkityksessä. Tämä tarkoittaa, että transaktiot ovat vähemmän alttiita suoralle yleistyneelle frontrunningille, jonka botit skannaavat mempoolia. Vaikka Maximal Extractable Value (MEV) on edelleen olemassa L2: llä, sen uuttamismekanismit eroavat L1: stä, ja suora mempool sniping vähenee merkittävästi, mikä tarjoaa ennalta-arvattavamman täytäntöönpanoympäristön välittäjille.
- Asynkroninen palaute: Kun transaktio on lähetetty, palvelu lähettää Honeywall-palvelulle ilmoituksen, joka merkitsee, että transaktio on aloitettu ja vaatii seurantaa.
Honeywall Service: Post-Execution Validation and Security
Honeywall-palvelu toimii kriittisenä täytäntöönpanon jälkeisenä tarkistuksena ja vahvana turvallisuuskerroksena välimiesmenettelyrobotille. sen rooli on vahvistaa toteutettujen transaktioiden tulokset ja suojata haitallisia toimijoita vastaan.
- Transaction Outcome Monitoring: Kun Transaction Builder lähettää tapahtuman, Honeywall Service seuraa sen sisällyttämistä lohkoon ja sen lopputulosta.
- Voittojen kirjaaminen: Jos kauppa on onnistunut ja tuottaa voittoa (kuten simulaatiosta odotetaan), voittotiedot kirjataan suorituskyvyn seurantaan ja analysointiin.
- Epäonnistumisen analyysi: Jos transaktio epäonnistuu, Honeywall analysoi peruuttamisen syyn.
- Honeypot/Scam Detection and Blacklisting: A key security feature is its ability to identify “honeypot” tokens or pools that implement deceptive logic (e.g., allowing buys but preventing sells, or imposing exorbitant hidden taxes on sells).
- Ulkoisen palveluntarjoajan integrointi: Se integroituu ulkoiseen palveluntarjoajaan tai tietokantaan tunnetuista honeypot-sopimuksista viittaamaan epäonnistuneissa liiketoimissa käytettyihin pareihin ja tunnistamaan siten mahdolliset huijaukset.
- Dynamic Blacklisting: If a specific pair or pool is identified as an honeypot or problematic due to unexpected high taxes, it is immediately added to a database-backed blacklist. This ensures that the bot avoids these risky assets in future operations.
- Bloom-suodattimen integrointi: Tämä musta lista hallitaan tehokkaasti Bloom-suodattimen mekanismin kautta. Tämä mahdollistaa Blockchain Data Reader -palvelun tarkistaa nopeasti äskettäin havaitut parit mustaa listaa vastaan ennen kuin jopa hakee varantojaan tai lisää ne markkinakaavioon.
Arkkitehtonisen suunnittelun lopputulos
Go:ssa toteutettu modulaarinen, tapahtumapohjainen arkkitehtuuri yhdistettynä erikoistuneisiin palveluihin tietojen syöttämiseen, markkinamallinnukseen, mahdollisuuksien optimointiin, nopeaan toteuttamiseen ja vankkaan turvallisuuteen muodostaa korkean suorituskyvyn välimiesmenettelyrobotin selkärangan.Tämä muotoilu varmistaa, että järjestelmä voi reagoida vertaansa vailla olevalla nopeudella vaihtuviin markkinamahdollisuuksiin samalla kun lieventää merkittäviä riskejä, jotka ovat ominaisia DeFi:lle "Dark Forest".
4. Opportunity detection ja optimaalinen täytäntöönpano: Botin aivot
Välimiesrobotin todellinen älykkyys on sen kyky tunnistaa nopeasti ja tarkasti kannattavat mahdollisuudet jatkuvasti muuttuvilla markkinoilla ja optimoida sen toteuttaminen maksimaalisen tuoton saavuttamiseksi.Tässä luvussa tutkitaan ydinalgoritmeja ja matemaattisia malleja, jotka tukevat robotin päätöksentekoprosessia, markkinoiden kartoittamisesta graafina optimaalisten kauppojen koon tarkkaan laskemiseen ja tulosten simulointiin.
DeFi-markkinoiden mallinnus graafina
Kuten arkkitehtuurin yleiskatsauksessa esitetään, Market Graph -palvelumme edustaa DeFi-maailmaa suunnatulla kaavalla. Tässä mallissa yksittäiset tokenit (esim. WETH, DAI, USDC) toimivatnodes, kun taas likviditeettikeskukset eri hajautetuissa pörsseissä (DEX) toimivatedgeskunkin reunan paino edustaa kaupan kustannuksia kyseisen poolin kautta.
Jotta voimme havaita tehokkaasti välimiesmenettelyyn liittyviä mahdollisuuksia, jotka ilmenevät kannattavin syklin muodossa, muutamme kannattavan kauppajärjestyksen löytämisen ongelman löytämiseksi.negative cycleTämä muutos saavutetaan soveltamalla logaritmisia funktioita valuuttakursseihin.
Logaritmin tarve syklin havaitsemisessa
Välimiesmenettelyn taustalla oleva keskeinen ajatus on kertoa aloitusmäärä useilla valuuttakursseilla, jotta päädytään enemmän alkuperäiseen omaisuuteen.TokenX
ja kauppaa sitäTokenY
SittenTokenY
puolestaTokenZ
ja lopuksiTokenZ
TakaisinTokenX
Lopullinen summa olisi:
Graafisten algoritmien tuotteiden kanssa työskentely on hankalaa. Yhteinen tekniikka laskennallisessa rahoituksessa moninkertaisten ongelmien muuntamiseksi additiivisiksi ongelmiksi on soveltaa logaritmia. Ottamalla kunkin valuuttakurssin luonnollinen logaritmi tuote tulee summaksi:
Nyt, kannattavan kierron kannalta tarvitsemmeln(Lopullinen) > ln(A)Mikä tarkoittaaln(RateX→Y) + ln(RateY→Z) + ln(RateZ→X) > 0Kuitenkin tyypilliset lyhyimmän polun algoritmit (kuten Bellman-Ford, jota käytämme) on suunniteltu löytämään polkuja, joilla on vähintäänsummaaJotta kannattava sykli näkyisi ”negatiivisena sykkelinä” kaaviossamme, kiellämme yksinkertaisesti logaritmiset nopeudet:
ln(RateX→Y) + ln(RateY→Z) + ln(RateZ→X) > 0Tällä muutoksella negatiivisten painojen summa, joka johtaa negatiiviseen arvoon (eli negatiivinen sykli), osoittaa suoraan kannattavan välimiesmenettelyn mahdollisuuden.
Tarkkuus käsitteleeBigInt
DeFi-merkkien määrä voi vaihdella suuresti, pienistä murto-osista (esimerkiksi ERC-20-merkkien osalta, joissa on 18 desimaalia paikkaa) hyvin suureen määrään (esimerkiksi stablecoineihin). Tämä äärimmäinen monimuotoisuus, joka ulottuu 18 merkittävään numeroon, tekee tavanomaisesta kelluvasta pisteestä aritmeettisesti erittäin alttiita tarkkuusvirheille.
Tämän voittamiseksi Market Graph -palvelumme ja itse asiassa kaikki laskelmat, joihin liittyy tokenimääriä ja valuuttakursseja botin sisällä, käyttävät Go: nmath/big
Paketti erityisestiBigInt
Aritmeettinen kokonaisuus jaBigFloat
Käytettävissä olevia laitteita tarvittaessa, kunBigFloat
Tarjoaa mielivaltaista tarkkuutta, soveltaalog
KaksiBigInt
taiBigFloat
Käyttö vaatii huolellista käsittelyä, kuten tavallisestimath.Log
Toiminto toimii nativillafloat64
Mukautetut täytäntöönpanot tai ulkoiset kirjastot, jotka kykenevät mielivaltaiseen tarkkuuslogaritmiin, ovat täällä välttämättömiä.
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)
}
Arbitraattipolun havaitseminen: Bellman-Fordin algoritmi
Kun DeFi-markkinat on mallinnettu tarkasti graafina, jossa on logaritmiset negatiiviset reunat, välimiesmenettelyyn liittyvien mahdollisuuksien löytämisen tehtävä vähenee tunnistamaannegative cyclesTätä tarkoitusta varten käytämme tätäBellman-Ford algorithm.
Named after Richard Bellman and Lester Ford Jr., Bellman-Ford is a versatile shortest path algorithm capable of handling graphs with negative edge weights. Unlike Dijkstra’s algorithm, which fails in the presence of negative cycles, Bellman-Ford is specifically designed to detect them. Its historical significance extends beyond theoretical computer science; it has found applications in diverse fields, including network routing (where it helps find the cheapest paths with varying costs) and, critically, in quantitative finance for identifying profitable trading opportunities in currency markets.
Algoritmi toimii iteratiivisesti rentouttaen reunoja, etsimällä asteittain lyhyempiä polkuja kaikkiin solmuihin lähteestä. Jos V−1 iteraatioiden jälkeen (jossa V on huippujen lukumäärä), ylimääräinen N-toinen iteraatio löytää polun, joka voi edelleen olla "rentoutunut" (eli lyhyempi polku löytyy), se osoittaa negatiivisen syklin läsnäolon. Tämä ominaisuus tekee siitä täydellisen meidän käyttötapauksessamme: negatiivinen sykli merkitsee kaupankäynnin sarjaa, joka johtaa nettovoittoon, juuri sitä, mitä välimiesrobotti etsii.
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
}
Optimal Input Amount Calculation: Maximizing Profit
Kun negatiivinen sykli (välimiesmenettelyn mahdollisuus) on tunnistettu, seuraava kriittinen vaihe on määrittääoptimal input amountTämä ei ole mielivaltaista; välimiesmenettelyn mahdollisuuden kannattavuus on kaupankäynnin koon epälineaarinen ominaisuus AMM-vaihtosopimuksiin liittyvän luontaisen liukumisen ja maksujen vuoksi.
As detailed in “An analysis of Uniswap markets”, the constant product formula inherently implies a convexity in the relationship between input and output amounts. Specifically, as the trade size increases, the effective exchange rate worsens due to the pool’s invariant. This means there’s a sweet spot: too small an amount might not cover gas fees, while too large an amount might incur excessive slippage, eroding profits.
Voittojen maksimointi onconvex optimization problemVälimiesmenettelyn polun N-vaihtosarjan osalta lopullinen tuotantomäärä (ja siten voitto) voidaan ilmaista alkuperäisen syöttömäärän (dx) funktiona.Vaikka tarkka analyyttinen ratkaisu usean jalkan välimiesmenettelyyn voi olla monimutkainen, etenkin vaihtelevien palkkarakenteiden ja liukuvien käyrien kanssa eri AMM:ien välillä, voittoa miinus kustannuksia (mukaan lukien kaasu) edustava funktio on yleensä karkea.
Arbitraatiostrategiamme ratkaisee tämän käyttämällä Go: n optimointiratkaisuagonum/optimize
Tämä ratkaisija ottaa toiminnon, joka edustaa nettovoittoa (voittoa swapista miinus arvioidut kaasumaksut ja mahdolliset flash-lainan maksut) ja löytää syöttömäärän, joka maksimoi tämän arvon.amountOut
muotoiludy = (x + dx) / (dx⋅ y)
jokaiselle vaiheelle välimiesmenettelyn polulla, välivarausten, maksujen ja liukumisen huomioon ottaminen jokaisessa vaiheessa.
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
}
Swap-simulointi ja kannattavuuden arviointi
Ennen kuin jokin transaktio lähetetään, välimiesmenettelystrategia suorittaa yksityiskohtaisensimulated executionTämä vaihe on ratkaisevan tärkeä todellisen kannattavuuden todentamiseksi ottaen huomioon reaaliaikaiset markkinaolosuhteet ja ehdotetun kaupan tarkat parametrit.
Simulaatiossa käytetään mukana olevien likviditeettikeskusten nykyisiä varantoja ja laskettua optimaalista syöttömäärää.Kunkin askeleen osalta monivaiheisessa polussa käytetään erityistä AMM-kaavaa (esimerkiksi Uniswap V2-tyyppisten poolien jatkuva tuotekaava) odotetun tuotoksen laskemiseksi:
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
}
Tärkeää on, että simulaatio sisältää myösminimum output amount (minOut)tarkistaa jokaisen välivaiheen.minOut
arvot johtuvat simuloiduista odotetuista tuotoksista ja asetetaan parametreiksi todellisessa ketjussa tapahtuneessa transaktiossa.Jos verkon latenssin, etumatkan tai odottamattomien markkinaolosuhteiden vuoksi todellinen ketjussa tapahtuva swap tuottaa vähemmän kuin määritettyminOut
Tämä mekanismi on elintärkeä suojakeino, joka estää bottia suorittamasta kannattamatonta kauppajärjestystä ja rajoittaa tappioita vain käännetylle kaupalle käytetylle kaasulle.
Ainoastaan, jos lopullinen nettotulos kaikkien maksujen, laskujen, kaasun kustannusten ja flash-lainan maksujen jälkeen ylittää ennalta määritellyn määrän.profit threshold (e.g., 0.5% of the initial input amount) is the opportunity deemed viable and passed to the Transaction Builder Service for execution. This threshold ensures that the bot only pursues opportunities with a significant enough margin to warrant the computational and on-chain costs.
Transaktiotekniikka: nopea teloitus pimeässä metsässä
Hyödyllisen välimiesmenettelymahdollisuuden tunnistaminen on vain puolet taistelusta; toinen, luultavasti kriittisempi, puoli on kyky suorittaa kauppa vertaansa vailla nopeudella ja luotettavuudella. DeFi: n hyper-kilpailukykyisessä "Pimeässä metsässä", jossa mahdollisuudet ovat epävakaat ja hienostuneet botit vievät jokaisen millisekunnin, transaktiotekniikasta tulee taidemuoto.Transaction Builder ServiceSuunniteltu varmistamaan salaman nopea ja turvallinen suorittaminen.
The Imperative of Speed
Arbitraatiomahdollisuuksien kannattavuusikkuna hajautetuissa pörsseissä mitataan usein millisekunneissa. Hintaeroja havaitaan nopeasti ja hyödyntävät lukuisat automatisoidut järjestelmät, mikä luo kovaa kilpailua siitä, että ensimmäinen sisällyttää kannattavan liiketoimen uuteen lohkoon. Mikä tahansa viivästys, vaikka pieni, voi johtaa siihen, että kilpailija tarttuu mahdollisuuteen, mikä johtaa epäonnistuneeseen liiketoimeen ja hukkaan kaasumaksuihin.
In-Memory -optimointi välitöntä transaktioiden rakentamista varten
Tarvittavan nopeuden saavuttamiseksi järjestelmämme priorisoi kaikkien keskeisten transaktiokomponenttien helposti saatavilla olevan muistin, mikä eliminoi kalliit I/O-toiminnot tai ketjupuhelut kriittisen transaktioiden rakentamisvaiheen aikana.
- Pre-parsetted and Packed ABIs: Smart Contract Application Binary Interfaces (ABIs) määrittelevät, miten vuorovaikutus sopimusten kanssa tapahtuu. Sen sijaan, että ABI-määritelmät ja koodaustoiminnon kutsuja lennettäisiin kunkin transaktion yhteydessä, järjestelmämme esparsettelee ja pakkaa tarvittavat ABI-tietorakenteet ja -toiminnon valinnat raaka-byte-sarjoihin. Nämä yleisten sopimusten vuorovaikutusta varten valmiiksi lasketut byte-sarjat (esim. swapExactTokensForTokens, flashLoanSimple, transferFrom) tallennetaan muistiin. Kun välimiesmenettelyyn liittyvät mahdollisuudet tunnistetaan, Transaction Builder voi nopeasti koota puhelutiedot
- Cached On-Chain Data for Transaction Fields: To avoid redundant on-chain calls for transaction metadata, a dedicated utility structure within the bot maintains critical, frequently updated values in memory:
- Tili Nonce: Nonce (osoitteesta lähetettyjen transaktioiden määrä) on ratkaisevan tärkeä toistohäiriöiden estämiseksi ja transaktioiden järjestämisen varmistamiseksi.Se kerätään kerran ja sitten hallitaan asteittain muistiin, jossa on vankka virheen käsittely, joka synkronoidaan uudelleen, jos transaktio epäonnistuu tai on odottamattomasti sisällytetty pois järjestyksestä.
- Optimaaliset kaasuparametrit: Sen sijaan, että verkko kysyisi kaasun hintoja (tai EIP-1559-ketjujen peruspalkkioita/prioriteettipalkkioita) jokaisesta transaktiosta, bot kerää säännöllisesti optimaaliset kaasuparametrit.
- Signer Information: The private key of the bot’s wallet and the associated
signer
object (used for cryptographically signing transactions) are loaded into memory upon initialization. This prevents any disk I/O or key derivation during the critical execution phase, ensuring that transactions can be signed almost instantaneously.
Säilyttämällä nämä elintärkeät komponentit muistiin, Transaction Builder Service voi rakentaa ja allekirjoittaa täydellisen blockchain-liiketoiminnan vain mikrosekunneissa, valmiina välittömään lähettämiseen.
Dynaaminen älykkään sopimuksen valinta: Flash-lainat vs. Suorat swapit
Välimiesmenettelystrategian palvelu välittää optimoidun välimiesmenettelyn polun ja lasketun optimaalisen syöttömäärän Transaction Builderille.amountIn
ja ylittääkö se ennalta määritellyn pääoman kynnyksen (tai jos strategia nimenomaisesti sitä vaatii), Transaction Builder valitsee dynaamisesti kahden ensisijaisen älykkään sopimuksen välillä täytäntöönpanoon:
- Suora swap-toimeenpanosopimus: Mahdollisuuksille, jotka voidaan rahoittaa suoraan botin omistamasta pääomasta, rakentaja käyttää executeArb-toimintoa (tai vastaavaa) mukautetussa multi-swap-proxy-sopimuksessa. Kuten luvussa 3 on esitetty, tämä sopimus ottaa syöttötunnukset botin lompakosta ja suorittaa koko swap-sekvenssin yhdellä atomipohjaisella transaktiolla.
- Flash Loan Integrated Contract: Kun laskettu optimaalinen määräIn välimiesmenettelyyn on huomattavasti suurempi kuin botin käytettävissä oleva pääoma, rakentaja kohdistaa erillisen, räätälöidyn älykkään sopimuksen, joka on suunniteltu käynnistämään ja hallitsemaan flash-lainoja. Tämän sopimuksen käynnistysArbitrage-toiminto (kuten luvussa 3 on yksityiskohtaisesti kuvattu) pyytää flash-lainaa pöytäkirjasta, kuten Aave, joka sitten kutsuu takaisin sopimuksen toteuttamaanOperation-toiminto.
Tämä dynaaminen valinta takaa tehokkaan pääoman kohdentamisen ja optimaalisen strategian toteuttamisen kunkin havaitun mahdollisuuden erityispiirteiden perusteella.
Mempool Dynamics: Ethereum L1 vs. Layer 2 ketjujen navigointi
Kriittinen osa välimiesmenettelyn täytäntöönpanoa on ymmärtää blockchainin transaktioiden leviämismekanismi, erityisestimempool.
-
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.
Node-nopeus ja turvallisuus: luotettavan täytäntöönpanon perusta
Yhteys lohkoketjuun on kaikkien tietojen ja transaktioiden yksittäinen sisään- ja ulospääsypiste. sen nopeus ja turvallisuus ovat tärkeitä:
- High-Performance Node Connection: The Transaction Builder Service connects to a dedicated, high-performance node provider (e.g., Alchemy, Infura, or a self-hosted node). A fast and low-latency connection is essential to minimize the time between signing a transaction and its propagation to the network. Any network delay here translates directly into lost arbitrage opportunities. Redundancy (connecting to multiple nodes) can also be considered for maximum reliability.
- Node-turvallisuus ja eheys: Yhdistetyn solmun turvallisuus on yhtä tärkeää. Hyvämaineisten solmun tarjoajien käyttäminen tai erittäin turvallisen itsehostitun solmun varmistaminen on ratkaisevan tärkeää, jotta vältetään ihmisen välinen hyökkäys tai tietojen väärinkäyttö. Vaarantunut solmu voi mahdollisesti vuotaa yksityisiä avaimia, pistää haitallisia liiketoimia tai manipuloida tietoja, mikä johtaa katastrofaalisiin tappioihin. Järjestelmämme riippuvuus yksityisistä RPC-päätteistä (jos saatavilla palveluntarjoajilta) ja turvallisista viestintäkanavista (https for HTTP, wss for WebSockets) vahvistaa tätä turvallisuutta.
Optimoimalla huolellisesti nopeuden jokaisella kerroksella, muistitietorakenteista ja esitietokoneista strategiseen ketjuvalintaan ja vankkaan solmujen infrastruktuuriin, arbitrage-bottimme on suunniteltu ylittämään kilpailijat ja hyödyntämään turvallisesti DeFi-maailman kiertäviä mahdollisuuksia. seuraavassa luvussa keskustelemme kriittisistä operatiivisista strategioista, joita tarvitaan tällaisen korkeatasoisen järjestelmän ylläpitämiseen ja kehittämiseen.
6. Pimeän metsän navigointi: haasteet, etiikka ja tulevaisuuden näkymät
Välimiesmenettelyn botin rakentaminen ja käyttö DeFi: ssä ”Dark Forest” on todiste hajautettujen teknologioiden voimasta, mutta se tuo myös esiin merkittäviä haasteita ja eettisiä näkökohtia. Vaikka järjestelmämme osoittaa automatisoidun välimiesmenettelyn teoreettisen ja käytännön toteutettavuuden, on ratkaisevan tärkeää tunnustaa vastakkainasettelun maisema ja sen laajemmat vaikutukset.
Pysyvä taistelu haitallisia toimijoita vastaan: Bloomin rooli
Alkuperäinen optimismi DeFi: n luvattoman luonteen ympärillä on valitettavasti lieventynyt haitallisten toimijoiden leviämisellä.Honeywall ServiceSe on elintärkeä viimeinen puolustuslinja, mutta näiden pahojen toimijoiden kekseliäisyys vaatii jatkuvasti kehittyvää vastatoimia.
Tärkeä osa tätä puolustusta onBloom filterBloom-suodatin on todennäköisyystietorakenne, joka voi nopeasti ja tehokkaasti testata, onko elementti joukon jäsen. Se on erittäin tilaa säästävä, mutta sillä on pieni todennäköisyys "vääräpositiivisille" (joka osoittaa, että elementti on joukossa, kun se ei ole), mutta ei koskaan "vääränegatiivisia". Meidän kontekstissamme Bloom-suodatinta käytetään ennalta suodattamaan tuleviin tapahtumiin liittyviä tietoja Blockchain Data Reader -palvelusta. Se sisältää tunnettujen haitallisten tai korkean verotuksen likviditeettiparien osoitteiden hashit. Ennen yksityiskohtaista käsittelyä tai varauksen keräämistä Bloom-suodattimen nopea tarkistus voi välittömästi hylätä tunnetut ongelmalliset parit, mikä estää tietojen
Despite the sophisticated pre-checks implemented in our custom ArbHelperMap
Älykäs sopimus (erityisesti_checkTaxLimit
Logiikka, joka simuloi kierrosvaihtoa verojen arvioimiseksi), jotkut haitalliset parit onnistuvat silti ohittamaan nämä alkuperäiset ketjun validoinnit.getAmountsOut
Funktio (käytetään hintakyselyihin) palauttaa näennäisesti normaalit, alhaisen verotuksen tuotot. Kuitenkin todellinen "honeypot" logiikka on upotettu syvemmälle todelliseenswapExactTokensForTokens
tai taustallatransfer
Nämä toiminnot saattavat asettaa liiallisia piilotettuja veroja (esim. 99 %) myyntioperaatioille tai jopa rajoittaa myyntiä kokonaan, tehokkaasti anastamalla varoja.
Testin aikana tapasimme huomattavan määrän tällaisia petollisia pareja.Olen henkilökohtaisesti kerännyt joitakin pareja osoitteita, jotka läpäisivät onnistuneesti alkuperäisengetAmountsOut
tarkistaa, mutta paljasti piilotettuja veroja tai myydä rajoituksia vain todellisen (simuloidun tai käännetyn) tapahtuman aikana paikallisessa tietokannassa. Tämä db-tiedosto asetetaan julkisesti saataville projektin GitHub-varastoon, joka toimii yhteisön resursseina auttaakseen muita välttämään näitä ansoja.
Eettiset vaikutukset ja pimeän metsän varjo
”Pimeä metsä” -analogia soveltuu paitsi robottien keskinäiseen kilpailuun myös laajempaan DeFi: n eettiseen maisemaan. välimiesmenettelyn tehokkuus, vaikka se on ratkaisevan tärkeää markkinoiden terveydelle ja hintojen löytämiselle, liittyy terävään todellisuuteen: välimiesten tuottamat voitot edustavat usein vähemmän hienostuneilta markkinaosapuolilta saatuja arvoja.
Täydellinen kulttuuri onFOMO (Fear Of Missing Out), yhdistettynä yleiseen ymmärtämättömyyteen taustalla olevista blockchain-mekanismeista ja rahoitusvälineistä, tekee monista vähittäiskaupan käyttäjistä helpon saaliin tässä ympäristössä. he tulevat erittäin epävakaille markkinoille, vuorovaikutuksessa uusien protokollien kanssa ja toteuttavat kauppoja ilman, että he ovat täysin tietoisia käsitteistä, kuten liukuvista, MEV: stä tai piilotetuista sopimuksista.
Tämä dynaaminen, mutta taloudellisesti looginen niille, joilla on kehittyneitä työkaluja, heittää varjoa hajautettujen teknologioiden maineelle. Tarina voi nopeasti siirtyä ”rahoituksellisesta voimaannuttamisesta” ”raiskauskäyttäytymiseen”, mikä heikentää luottamusta tilaan, jossa muutoin on valtava lupaus. DeFi: n ytimessä pyritään demokratisoimaan rahoitusta tarjoamalla luvatonta pääsyä ja avoimuutta. Kuitenkin MEV: n hienostunut luonne ja petosten yleisyys voivat vahingossa heikentää näitä ihanteita luomalla kaksitasoisen järjestelmän, jossa vain teknisesti ammattitaitoinen voi todella navigoida turvallisesti. On välttämätöntä, että rakentajina tunnustamme nämä eettiset ulottuvu
Alkuperäinen nimi: Still Navigating the Dark Forest
Huolimatta DeFi-maisemien luontaisista monimutkaisuuksista ja jatkuvista haasteista, tämän arbitrage-botin suunnittelun matka on ollut merkittävä validointi teoreettisista periaatteista, jotka täyttävät käytännön toteutuksen.speed, precision, and data-driven insights, joka kykenee havaitsemaan ja toteuttamaan monen jalkojen välimiesmenettelyyn liittyviä mahdollisuuksia.
Aluksi yleinen odotus ”Pimeän metsän” sisällä oli, että valtaosa välimiesmenettelyn arvosta olisi välittömästi siepattu suurilla, hyvin varustetuilla pelaajilla, hyödyntämällä itse isännöityjä solmuja ja suoraa pääsyä lohkojen tuottajiin.
Vaikka kannattava välimiesmenettely vanhemmilla AMM-malleilla, kuten Uniswap V2:lla (jotka ovat ensisijaisesti riippuvaisia jatkuvista tuotepuistoista), voi olla haastavaa ylläpitää pitkällä aikavälillä kaasun kustannusten kiihtymisen ja lisääntyneen kilpailun vuoksi, "Pimeä metsä" kehittyy edelleen. Uusimmat toteutukset, kuten Uniswap V3: n Keskitetty likviditeetti AMM (CLAMM), ottavat käyttöön uusia välimiesmenettelyvektoreita, jotka edellyttävät kehittyneempää mallintamista, mutta tuottavat usein korkeampia tuottoja lisääntyneen pääoman tehokkuuden vuoksi. Lisäksi kasvava cross-chain-välimiesmenettely, siltojen hyödyntäminen ja lohkoketjun väliset viest
Joten vaikka olen vielä köyhä, voin luottavaisesti sanoa, että minusta on tullut erinomainen metsämatkailija.My compass is sharper, my map more detailed, and I understand the whispers of the canopy.
Hankkeen tallennus
Niille, jotka haluavat sukeltaa syvemmälle käytännön täytäntöönpanoon ja todellisiin tietoihin joidenkin keskusteltujen "sankareiden" takana, kooditietokannan sanitoitu versio ja tietokanta, joka on täynnä tunnettuja haitallisia tunnusmerkkipareja, ovat käytettävissä minunGitHubin tallennusNämä 85 erityistä paria, vaikka numeerisesti pieniä, tuottavat suhteettoman merkittävän kauppamäärän, koska ne yrittävät jatkuvasti houkutella naiiveja robotteja kannattamattomiin kauppoihin.
GitHubin tallennusViittaukset
- Dan Robinson, Georgios Konstantopoulos. ”Ethereum on pimeä metsä”,* Paradigma.
- Guillermo Angeris, Hsien-Tang Kao, Rei Chiang, Charlie Noyes ja Tarun Chitra. ”Uniswap-markkinoiden analyysi”, Cryptoeconomic Systems.
- Claudio Gebbia. ”Analyysi ja täytäntöönpano välimiesmenettely Bots keskitetyssä ja hajautetussa rahoituksessa”, University of Zurich.
- Y. Zhang, Z. Li, T. Yan, Q. Liu, N. Vallarano ja C. J. Tessone, ”Profit Maximization in Arbitrage Loops”.