As bolsas descentralizadas (DEXs) dependem de reservas de tokens para determinar os preços de swap, permitindo negociações sem permissão, mas também introduzindo oportunidades de MEV involuntariamente. Como os invasores podem reordenar, inserir ou remover transações em torno de negociações DEX, eles podem explorar discrepâncias temporárias de preços para extrair lucro por meio de arbitragem ou ataques sanduíche.
A pesquisa MEV é um problema de otimização: dado um mempool e um ambiente DEX, queremos avaliar milhares, às vezes milhões de pacotes de transações possíveis e escolher o mais lucrativo.
Para diagnosticar os gargalos, reproduzimos sete exemplos históricos de arbitragem MEV (veja o Apêndice) usando duas ferramentas de última geração:
- Foundry, o EVM do lado da CPU mais rápido em Rust
- Lanturn, um pesquisador MEV em TypeScrip
Ambiente:
- Intel i7
- RTX3090Ti 24G
- SSD 1T
- Ubuntu 22.04
Executamos 1.000 replays para cada ferramenta e medimos como o tempo é dividido nos três estágios principais:
- Bifurcação do estado mainnet
- Gerando pacotes de entrada
- Executando contratos inteligentes
Nossas descobertas correspondem a pesquisas anteriores: a geração de entrada é trivial (<1%), mas a execução e a bifurcação de EVM dominam a latência de ponta a ponta. Gastos com fundição:
- 80,89% de seu tempo na bifurcação (27,87 ms)
- 18,82% na execução de swaps (6,49 ms)
Lanturn tem desempenho ainda pior: sua execução EVM é 17,8× mais lento e bifurcação 1,98× mais lento do que o Foundry, apesar do multi-threading.
Resumindo: a pesquisa MEV é limitada pela velocidade de execução da CPU, e as CPUs simplesmente não conseguem explorar o espaço de pesquisa com rapidez suficiente.
Para sair desse gargalo de CPU, usamos GPU:
- Escreva o bot MEV no Solidity (por exemplo, um roteador realizando arbitragem multi-hop)
- Compile o contrato inteligente para LLVM IR usando mau
- Gere código PTX (montagem CUDA) usando backend LLVM
- Execute-o nativamente em threads de GPU
Aqui está o bot Solidity que usamos como exemplo de execução. Seu manipulador de fallback analisa um formato de byte compactado que descreve as trocas, determina o tipo de DEX e chama o correto swap() função:
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.6;
import "./libraries/uniswapv2/UniswapV2Pair.sol";
import "./libraries/uniswapv3/UniswapV3Pair.sol";
import "./libraries/sushiswap/SushiswapPair.sol";
import "./libraries/pancakeswap/PancakeswapPair.sol";
contract MEV {
fallback(bytes calldata data) external payable returns (bytes memory) {
uint256 amount = abi.decode(data(:32), (uint256));
uint32 swap_len = uint32(abi.decode(data(32:), (bytes4)));
uint32() memory swap_vec = new uint32()(swap_len);
uint32() memory token_vec = new uint32()(swap_len);
uint32 calldata_size = uint32(data.length);
uint32 swaps_buf_size = (calldata_size - 32 - 4) / 2;
for (uint32 i = 0; i < swap_len; i++) {
swap_vec(i) = uint32(abi.decode(data(36 + i * 4:), (bytes4)));
uint256 token_word = abi.decode(data(36 + swaps_buf_size + 32 * (i / 8):), (uint256));
token_vec(i) = uint32(token_word >> (256 - 32 * (i % 8 + 1)));
}
for (uint32 i = 0; i < swap_len; i++) {
bool reversed = token_vec(i) > token_vec((i + 1) % swap_len);
uint32 swap_u32 = swap_vec(i);
uint8 dex_type = uint8(swap_u32 >> 24);
address dex = address(swap_u32 & 0xFFFFFF);
if (dex_type == 1) {
amount = UniswapV2Pair(dex).swap(reversed, amount);
} else if (dex_type == 2) {
amount = UniswapV3Pair(dex).swap(reversed, amount)
} else if (dex_type == 3) {
amount = SushiswapPair(dex).swap(reversed, amount);
} else if (dex_type == 4) {
amount = PancakeswapPair(dex).swap(reversed, amount);
} else if (dex_type == 5) {
continue;
}
}
return abi.encodePacked(amount);
}
}
Uma vez compilado para PTX, este bot se torna um código GPU executável. Em vez de avaliar um pacote de cada vez, como fazem as CPUs, lançamos dezenas de milhares de threads, cada uma testando um pacote candidato diferente.
Um algoritmo genético paralelo (GA) é usado para pesquisar pacotes na GPU. Cada thread de GPU representa um indivíduo (ou seja, um pacote) em uma população. Em cada geração, o algoritmo executa:
- Seleção – escolha os pacotes com maior lucro
- Cruzamento – recombiná-los em novos pacotes como descendentes
- Mutação – ajuste DEXs, tokens ou pedidos para obter novos pacotes como invariantes
- Avaliação – execute o bot MEV com os pacotes invariantes na GPU
Este fluxo de trabalho nos permite explorar um vasto espaço de pesquisa com extrema rapidez. Múltiplas populações podem ser avaliadas simultaneamente, permitindo uma cobertura de pesquisa ampla e profunda.
Tabela: Novas oportunidades de MEV identificadas em blocos do primeiro trimestre de 2025 (ETH)
| Lucro | Receita | Gás | |
|---|---|---|---|
| Arbitragem | 335,53 | 336,40 | 0,87 |
| Sanduíche | 90,90 | 103,60 | 12h70 |
| Total | 426,43 | 440,00 | 13.57 |
Em todos os experimentos, alcançamos de 3,3 milhões a 5,1 milhões de transações por segundo, superando o Lanturn em aproximadamente 100.000×. Com base em dados reais do primeiro trimestre de 2025, o sistema estimou oportunidades de MEV abrangendo de 2 a 14 transações, totalizando 426,43 ETH em lucro extraível.
Observe que o preço do gás depende do mercado naquele momento. Nós
O MEVISOR introduz dois tipos de sobrecarga: inicialização a frio e sobrecarga por pesquisa.
Cold Boost (uma vez)
Antes de pesquisar, a GPU deve carregar o bot PTX e inicializar a memória.
Isso custa 7,03 segundos, mas acontece apenas uma vez e é amortizado em todas as pesquisas futuras.
Sobrecarga de tempo de execução
O principal custo de tempo de execução é carregar instantâneos de estado DEX na memória da GPU.
À medida que escalamos de 64 para 540 pools DEX:
- A latência de carregamento permanece estável em aproximadamente 0,30 segundos
- O uso de memória da GPU aumenta linearmente (774 MB → 1,58 GB)
Mesmo com centenas de DEXs, o MEVISOR permanece confortavelmente abaixo dos limites de VRAM das GPUs comuns e mantém uma sobrecarga baixa e previsível.
Exemplos de motivação
| Comprimento | Bloquear | Capital (ETH) | Receita (ETH) | Cadeia DEX | Cadeia de Ativos |
|---|---|---|---|---|---|
| 2 | 21536202 | 0,05 | 0,0002 | 0x1DC698b3d2995aFB66F96e1B19941f990A6b2662, 0x9081B50BaD8bEefaC48CC616694C26B027c559bb |
0x4c11249814f11b9346808179Cf06e71ac328c1b5, 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
| 3 | 14079213 | 0,12 | 0,0009 | c926990039045611eb1de520c1e249fd0d20a8ea, 62ccb80f72cc5c975c5bc7fb4433d3c336ce5ceb, 77bd0e7ec0de000eea4ec88d51f57f1780e0dfb2 |
0x557B933a7C2c45672B610F8954A3deB39a51A8Ca, 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 0xe53EC727dbDEB9E2d5456c3be40cFF031AB40A55 |
| 4 | 12195667 | 0,64 | 0,0196 | 0x1f44e67eb4b8438efe62847affb5b8e528e3f465, 0x41ca2d9cf874af557b0d75fa9c78f0131c7f345c, 0x088ee5007c98a9677165d78dd2109ae4a3d04d0c, 0xa478c2975ab1ea89e8196811f51a7b7ade33eb11 |
0x6b175474e89094c44da98b954eedeac495271d0f, 0xbcda9e0658f4eecf56a0bd099e6dbc0c91f6a8c2, 0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e, 0x6b175474e89094c44da98b954eedeac495271d0f |
| 5 | 13734406 | 2.04 | 0,0452 | 0x60594a405d53811d3bc4766596efd80fd545a270, 0x1d42064fc4beb5f8aaf85f4617ae8b3b5b8bd801, 0x9f178e86e42ddf2379cb3d2acf9ed67a1ed2550a, 0xfad57d2039c21811c8f2b5d5b65308aa99d31559, 0x5777d92f208679db4b9778590fa3cab3ac9e2168 |
0x6b175474e89094c44da98b954eedeac495271d0f, 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984, 0x514910771af9ca656af840dff83e8264ecf986ca, 0x6b175474e89094c44da98b954eedeac495271d0f |
| 6 | 14530401 | 0,41 | 0,0182 | 0xa478c2975ab1ea89e8196811f51a7b7ade33eb11, 0x5ab53ee1d50eef2c1dd3d5402789cd27bb52c1bb, 0x59c38b6775ded821f010dbd30ecabdcf84e04756, 0x9f178e86e42ddf2379cb3d2acf9ed67a1ed2550a, 0x153b4c29e692faf10255fe435e290e9cfb2351b5, 0x1f44e67eb4b8438efe62847affb5b8e528e3f465 |
0x6b175474e89094c44da98b954eedeac495271d0f, 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, 0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9, 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984, 0x514910771af9ca656af840dff83e8264ecf986ca, 0x6b175474e89094c44da98b954eedeac495271d0f |
| 7 | 13731798 | 0,24 | 0,0202 | 0x1f44e67eb4b8438efe62847affb5b8e528e3f465, 0x153b4c29e692faf10255fe435e290e9cfb2351b5, 0x14243ea6bb3d64c8d54a1f47b077e23394d6528a, 0xd75ea151a61d06868e31f8988d28dfe5e9df57b4, 0x088ee5007c98a9677165d78dd2109ae4a3d04d0c, 0x41ca2d9cf874af557b0d75fa9c78f0131c7f345c, 0x1f44e67eb4b8438efe62847affb5b8e528e3f465 |
0x6b175474e89094c44da98b954eedeac495271d0f, 0xbcda9e0658f4eecf56a0bd099e6dbc0c91f6a8c2, 0x514910771af9ca656af840dff83e8264ecf986ca, 0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9, 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, 0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e, 0x6b175474e89094c44da98b954eedeac495271d0f |
| 8 | 13754757 | 2,48 | 0,0680 | 0xa478c2975ab1ea89e8196811f51a7b7ade33eb11, 0x5ab53ee1d50eef2c1dd3d5402789cd27bb52c1bb, 0x59c38b6775ded821f010dbd30ecabdcf84e04756, 0x1d42064fc4beb5f8aaf85f4617ae8b3b5b8bd801, 0x11b815efb8f581194ae79006d24e0d814b7697f6, 0xfcd13ea0b906f2f87229650b8d93a51b2e839ebd, 0xc0067d751fb1172dbab1fa003efe214ee8f419b6, 0x60594a405d53811d3bc4766596efd80fd545a270 |
0x6b175474e89094c44da98b954eedeac495271d0f, 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, 0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9, 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984, 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, 0xdac17f958d2ee523a2206206994597c13d831ec7, 0x4206931337dc273a630d328da6441786bfad668f, 0x6b175474e89094c44da98b954eedeac495271d0f |
Fontesethresear



