Cross-chain, DeFi e contratos inteligentes · Aula 2 de 6
Swaps em DEXs, exchanges instantâneas e fluxos de liquidez
14 min de leitura
Quase todo rastro de lavagem de dinheiro envolve uma mudança de ativo em algum ponto, e a forma como essa mudança ocorre determina a robustez do próximo vínculo. Um swap em uma exchange descentralizada (DEX) é registrado em uma única transação, com o evento do pool, as transferências de tokens e as reservas antes e depois. Um protocolo de swap entre blockchains pode registrar o destino na blockchain de origem e a origem na blockchain de destino. Um serviço de exchange instantânea ou uma mesa OTC deixa apenas um depósito de um lado e um pagamento do outro. Esta aula mostra como interpretar cada tipo de swap como evidência, o que os eventos de liquidez revelam, quais registros existem fora da blockchain e o que você pode afirmar sobre cada vínculo. A decodificação geral está na Aula 5.1, a correspondência de etapas entre blockchains na Aula 5.3 e as pontes na Aula 5.4.
Como interpretar um swap em DEX
Pools, token0 e token1
Um par no estilo Uniswap v2 é um contrato que mantém dois tokens. O token com o menor endereço é token0 e o outro é token1; a ordem é fixada na criação e não tem relação com qual token representa "o preço". Todos os eventos informam os valores nessa ordem, portanto consulte token0, token1 e as casas decimais de ambos antes de converter qualquer valor.
O evento da v2 é Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to), topic0 0xd78ad95f…d822. Após cada alteração nas reservas, o par também emite Sync(uint112 reserve0, uint112 reserve1). Um swap decodificado em um par no qual token0 é USDC (6 casas decimais) e token1 é WETH (18 casas decimais):
{
"event": "Swap",
"pair": "0x3f8a…e2d1",
"sender": "0x7a2c…48d0",
"to": "0xa1b2c3d4…9f0e",
"amount0In": "0",
"amount1In": "5000000000000000000",
"amount0Out": "14880819116",
"amount1Out": "0",
"next_log": {"event": "Sync", "reserve0": "2985119180884", "reserve1": "1005000000000000000000"}
}
Entraram cinco WETH e saíram 14.880,819116 USDC, a um preço de execução de 2.976,16 USDC por WETH. O sender geralmente é um roteador, não o negociador, e to indica para onde foi a saída; confirme o negociador pelas transferências de tokens na mesma transação.
Outros modelos de pool
Os pools da Uniswap v3 emitem Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick), topic0 0xc42079f9…ca67, com valores com sinal do ponto de vista do pool: positivos para entradas no pool, negativos para saídas. Um swap de 2 WETH por USDC mostra amount0 = -5994120000 (saída de 5.994,12 USDC) e amount1 = 2000000000000000000 (entrada de 2 WETH). O preço após o swap é price_raw = (sqrtPriceX96 ÷ 2^96)², em unidades básicas de token1 por unidade básica de token0, multiplicado por 10^(decimals0 − decimals1). Para sqrtPriceX96 = 1446501726624926496477173928747177, price_raw ≈ 333.333.333,33; multiplicado por 10^−12, isso equivale a 0,000333333 WETH por USDC, ou 3.000 USDC por WETH (tick ≈ 196.256, pois price_raw = 1,0001^tick). Ignorar o ajuste de casas decimais resulta em um preço incorreto por um fator de 10^12.
A Uniswap v4 (2025) mantém todos os pools em um único PoolManager singleton, portanto o address do log não identifica mais o pool; quem o identifica é o id indexado do pool. Seu evento Swap (topic0 0x40e9cecb…112f) usa sinais nos valores do ponto de vista do usuário, o oposto da v3. Os pools da Curve emitem TokenExchange com índices das moedas. Mantenha um decodificador por protocolo e versão, testado em uma transação cujo resultado você conheça.
Quatro regras para um rastreamento
- O vínculo é determinístico, o ativo muda. A entrada e a saída aparecem na mesma transação. Registre ambos os valores, a taxa efetiva e, para um valor em moeda fiduciária, a fonte do preço e o horário. Independentemente do método de rastreamento aplicado (Aula 3.3), a saída do swap é o produto de sua entrada.
- O pool não é uma contraparte. Um pool de liquidez é um contrato que mantém fundos de muitos provedores. Os fundos não "vão para" o proprietário do pool; siga a saída, não o pool.
- O destinatário pode ser diferente do remetente. Roteadores e agregadores aceitam um parâmetro de destinatário, portanto a saída pode ser paga a um endereço novo na mesma transação. Leia a chamada decodificada ou as transferências; nunca presuma que quem fez a chamada recebeu a saída.
- Apure o saldo líquido da rota. Um agregador divide uma ordem entre pools em uma única transação. O que saiu do investigado e o que chegou ao destinatário são os fatos; a rota é um detalhe.
Os contratos de DEX não têm um operador que mantenha registros, mas a interface usada pelo investigado pode ter: interfaces web e APIs de agregadores podem registrar endereços IP, agentes de usuário e solicitações de cotação, e aplicativos de carteira podem encaminhar swaps por suas próprias APIs. A retenção depende do operador.
Apuração do saldo líquido de uma rota de agregador
| logIndex | Token | De | Para | Valor |
|---|---|---|---|---|
| 10 | WETH | Negociador | Roteador | 10 |
| 11 | WETH | Roteador | Pool A (WETH/USDC) | 6 |
| 12 | USDC | Pool A | Roteador | 17.880 |
| 13 | WETH | Roteador | Pool B (WETH/DAI) | 4 |
| 14 | DAI | Pool B | Pool C (DAI/USDC) | 11.930 |
| 15 | USDC | Pool C | Roteador | 11.925 |
| 16 | USDC | Roteador | Negociador | 29.805 |
Apurar o saldo líquido das entradas e saídas de cada endereço reduz tudo a uma única afirmação: o negociador vendeu 10 WETH por 29.805 USDC, uma média de 2.980,50 USDC por WETH. O saldo líquido do roteador é zero, e o de cada pool corresponde à alteração de suas próprias reservas.
-- Variação líquida de tokens por endereço em uma transação
SELECT address, token_address, SUM(delta) AS net_raw
FROM (
SELECT to_address AS address, token_address, amount_raw AS delta
FROM token_transfers WHERE transaction_hash = '0x9e1d…b7a4'
UNION ALL
SELECT from_address, token_address, -amount_raw
FROM token_transfers WHERE transaction_hash = '0x9e1d…b7a4'
) t
GROUP BY address, token_address
HAVING SUM(delta) <> 0;
As etapas com ETH nativo devem ser adicionadas a partir dos rastros de execução. Em sistemas baseados em intenções, um solucionador, e não o usuário, envia a transação, portanto tx.from é o solucionador; identifique o usuário pelos eventos de negociação e pelas transferências do contrato de liquidação.
Fluxos de liquidez, impacto no preço e MEV
Adições e remoções
Adicionar fundos roubados a um pool e removê-los depois não é um swap: o depositante recebe um token de LP ou uma posição, e a remoção devolve a participação. Siga a posição, não o saldo do pool.
| Protocolo | Adição | Remoção | Registro de titularidade |
|---|---|---|---|
| Uniswap v2 | Mint(sender, amount0, amount1) mais Transfer do token de LP a partir do endereço zero | Tokens de LP enviados ao par, Burn(sender, amount0, amount1, to), Transfer de LP para zero | Token de LP fungível (o contrato do par) |
| Uniswap v3 | Mint do pool com intervalo de ticks; IncreaseLiquidity no gerenciador de posições | Burn do pool (credita tokens), depois Collect (efetua o pagamento deles); DecreaseLiquidity | NFT de posição (ERC-721) |
| Uniswap v4 | ModifyLiquidity no PoolManager | Mesmo evento, variação negativa de liquidez | Registros de posição, frequentemente um NFT |
Duas armadilhas: na v3, o Mint do pool mostra o gerenciador de posições como titular, portanto siga o NFT de posição até o verdadeiro provedor; e um Burn da v3 não movimenta tokens, o dinheiro sai em Collect. Um rug pull clássico ocorre quando quem implanta o contrato cria um token, adiciona liquidez, espera por compradores e depois remove quase toda a liquidez em uma única transação; os valores de Burn ou DecreaseLiquidity medem o que foi retirado.
Impacto no preço
O impacto no preço compara o preço de execução com o preço à vista do pool imediatamente antes da negociação. Para um par da v2, as reservas antes do swap equivalem às reservas em seu evento Sync menos as entradas mais as saídas. No swap acima: 2.985.119,18 + 14.880,82 = 3.000.000 USDC e 1.005 − 5 = 1.000 WETH, um preço à vista de 3.000.
| Medida | Valor |
|---|---|
| Preço à vista antes | 3.000,00 USDC por WETH |
| Preço de execução | 2.976,16 (−0,79%) |
| Saída sem a taxa de 0,30% | 14.925,37, preço de 2.985,07 (−0,50%) |
| Preço à vista depois (a partir de Sync) | 2.970,27 (−0,99%) |
Da diferença de 0,79%, cerca de 0,30% corresponde à taxa e 0,50% ao impacto puro no preço; o preço à vista variou cerca de duas vezes mais que o preço médio pago, algo normal em pools de produto constante. Um grande impacto em um pool com pouca liquidez sinaliza venda forçada, como um invasor se desfazendo de um token roubado.
Padrões de MEV
O valor máximo extraível (MEV) apresenta padrões reconhecíveis. Em um sanduíche, em um mesmo bloco e pool, o agente X compra o token T, uma vítima compra T e X vende T logo depois, frequentemente pagando diretamente ao construtor do bloco (uma transferência de ETH ao destinatário das taxas, visível nos rastros de execução); defina o agente como o contrato do bot que recebeu a saída, pois os bots alternam os endereços remetentes. A arbitragem atômica realiza swaps em um ciclo de pools (WETH → USDC → DAI → WETH) em uma única transação e termina com uma quantidade maior do token inicial. A liquidez just-in-time (JIT) consiste em um Mint da v3 imediatamente antes de um grande swap e um Burn e Collect logo depois, por um único endereço. As ocorrências detectadas são candidatas: verifique quantidades e lucro e descarte explicações inocentes, como dois arbitradores sem relação entre si.
Protocolos de swap entre blockchains: memos como evidência
Os protocolos de swap entre blockchains trocam ativos nativos entre blockchains por meio de cofres controlados pelos nós do protocolo. A THORChain é o exemplo de referência, e seus registros são especialmente úteis porque ambos os lados contêm texto que identifica o outro.
No lado de entrada, o usuário envia o ativo ao cofre do protocolo: em blockchains EVM, por meio de um contrato roteador que registra o memo em seu evento de depósito; no Bitcoin, em uma saída OP_RETURN, que a documentação do protocolo limita a 80 bytes. O formato do memo de swap é SWAP:ASSET:DESTADDR/REFUNDADDR:LIMIT/INTERVAL/QUANTITY:AFFILIATE:FEE (o endereço de reembolso é opcional), geralmente abreviado com = para um swap a mercado. No lado de saída, o cofre paga o ativo de destino em uma transação cujo memo é OUT: seguido do hash da transação de entrada; um swap que falha é reembolsado com um memo REFUND: contendo o mesmo hash. Um par fictício:
Ethereum (entrada, fictícia)
tx 0x9a3f…c21e de 0x3f9c…a1d7 para roteador de swap 130.0 ETH
memo do evento de depósito "=:BTC.BTC:bc1q…r7w2::xx:20"
Bitcoin (saída, fictícia)
txid 6d0b…e45a do cofre bc1q…v9tn
vout 0 5.16800000 BTC bc1q…r7w2
vout 1 OP_RETURN "OUT:9A3F…C21E"
O memo de entrada identifica o destinatário no Bitcoin; o memo de saída identifica a transação no Ethereum. O par pode ser verificado em ambas as blockchains a partir de seus próprios nós, e os registros públicos do protocolo fornecem uma terceira confirmação independente. Três detalhes são importantes:
- Tempo. Swaps em fluxo contínuo são executados como subswaps ao longo de vários blocos, e swaps com limite podem esperar em uma fila por até 43.200 blocos do protocolo (cerca de três dias) por padrão. Defina as janelas de tempo a partir dos parâmetros do memo.
- Afiliados. O campo de afiliado identifica, por um nome curto registrado, a interface ou carteira que construiu a transação: uma possível fonte de logs, embora o próprio protocolo não tenha nenhum.
- Memos de referência. Para economizar espaço no memo, um memo pode ser registrado antecipadamente e referenciado, por exemplo por uma referência codificada no valor; os registros expiram após o prazo do parâmetro
MemolessTxnTTL, por padrão 3.600 blocos (cerca de seis horas). Preserve o registro junto com as transações.
Outros protocolos usam campos diferentes, mas o método é o mesmo: encontre o que cada lado informa sobre o outro.
Serviços de exchange instantânea e mesas OTC
Os serviços de exchange instantânea convertem um ativo em outro sem uma conta: o usuário informa um endereço de pagamento, recebe um novo endereço de depósito para a ordem, envia os fundos e recebe o pagamento, frequentemente em outra blockchain. Muitos se autodenominam não custodiais porque não mantêm saldos, mas controlam os fundos entre o depósito e o pagamento, motivo pelo qual o rastro se interrompe ali, e trocar um ativo virtual por outro para um cliente ou em seu nome é uma atividade de VASP segundo a definição do FATF usada na Recomendação 15. Na blockchain, eles se parecem com qualquer serviço custodial: endereços de depósito por ordem, consolidações e pagamentos a partir de uma carteira quente. Sem registros, o vínculo entre depósito e pagamento é uma inferência de valor e tempo (Aula 5.3); com registros, ele é documentado. Um serviço pode manter:
| Registro | Uso probatório |
|---|---|
| ID da ordem, horário de criação, ativos e taxa cotada | Vincula um endereço de depósito a uma ordem |
| Endereço de depósito e txid do depósito | Confirma qual depósito pertence à ordem |
| Endereço de pagamento e txid do pagamento | Converte o vínculo inferido em um vínculo registrado |
| Endereço de reembolso | Frequentemente uma carteira controlada pelo investigado; vincula outras ordens |
| Endereço IP, agente de usuário, configurações de idioma | Pistas para atribuição (Aula 4.7) |
| E-mail ou contato fornecido para suporte | Identificador para medidas legais posteriores |
| ID de parceiro ou afiliado | Identifica a carteira ou o site que enviou a ordem |
| Sinalizações de risco, retenções e resultados de triagem | Mostra se o serviço congelou ou questionou a ordem |
Solicite todas as ordens que compartilhem o endereço de pagamento, o endereço de reembolso ou o endereço IP no período, não apenas a que você encontrou: o histórico frequentemente revela outras carteiras do investigado. Os IPs podem ser de VPNs e os dados de contato não são verificados. A cooperação costuma ser lenta, portanto envie solicitações de preservação assim que o depósito for identificado (Aula 1.4).
Uma mesa OTC negocia operações fora da blockchain e as liquida de e para seus próprios endereços. As etapas podem estar em blockchains diferentes, ou uma delas pode ser uma transferência bancária, portanto muitas vezes não há vínculo algum na blockchain; os registros da mesa (diligência devida, confirmações de negociação, instruções de liquidação, logs de conversas, dados bancários) são a única ponte. Um intermediário que negocia por meio de uma conta em uma exchange maior acrescenta uma camada: a exchange vê um único cliente, o intermediário (Aula 6.5).
O que você pode afirmar sobre cada vínculo de swap
| Evidência disponível | Base do vínculo | Redação em um relatório |
|---|---|---|
| Swap em DEX na mesma transação | Determinístico (grau A) | "Na transação T, X foi trocado por Y e pago ao endereço B" |
| Memo entre blockchains em ambas as blockchains | Determinístico em ambas as blockchains (grau A), também registrado pelo protocolo | "O protocolo pagou Z ao endereço B em relação à transação de entrada A" |
| Exchange instantânea, apenas valor e tempo | Inferência (grau D) | "Compatível com", com contagem de candidatos e taxa de correspondência por acaso |
| Exchange instantânea com registro da ordem | Confirmado por registro (grau B) | "Segundo os registros do serviço, a ordem N pagou Z ao endereço B" |
| Mesa OTC, sem registros | Nenhuma | "O destino desses fundos não é conhecido" |
Os graus são os da Aula 3.2. Um vínculo confirmado por registro é tão confiável quanto o próprio registro: identifique quem o produziu, a data de recebimento e o hash do arquivo conforme recebido.
Foco no exame: ordenação de token0/token1 e casas decimais; eventos Swap e Sync da v2; valores com sinal da v3 (positivos para entradas no pool) e conversão de sqrtPriceX96 com o ajuste de casas decimais; PoolManager da v4, id do pool e sinal invertido; swaps em DEX como vínculos determinísticos que mudam o ativo, pools não sendo contrapartes e parâmetros de destinatário; apuração do saldo líquido de uma rota de agregador e por que tx.from pode ser um roteador ou solucionador; NFTs de posição, Burn seguido de Collect e rug pulls; impacto no preço a partir das reservas; padrões de sanduíche, arbitragem e JIT; memos entre blockchains, OUT: e REFUND: contendo o hash de entrada, tempo dos swaps, afiliados e memos de referência; exchanges instantâneas como VASPs e seus registros; mesas OTC sem vínculo na blockchain; adequação da redação à base de cada vínculo.
Questões de prática
Verifique o que você aprendeu. Estas questões não contam para o exame.
Entre para salvar seu progresso e continuar de onde parou. É grátis. Entrar