Ataque utilizando a técnica front running

porMatheusem28/06/2022

Nesse artigo iremos aprender a como um contrato malicioso utiliza a técnica de front running para antecipar uma transação durante outra transação.

Vulnerabilidade

As transações levam algum tempo antes de serem executadas. Um invasor pode observar o pool de transações e enviar uma nova transação, incluindo-a em um bloco antes da transação original ser executada.
Esse mecanismo pode ser usado para reordenar transações em benefício do invasor.

Como funciona:
Alice cria um jogo de adivinhação. Você ganha 10 Ether se encontrar a string correta quere refere-se a hash de destino.

Vamos ver como esse contrato é vulnerável ao front running.

  1. Alice implanta FindThisHash com 10 Ether
  2. Bob encontra a string correta que refere o hash para o hash de destino. (Ethereum)
  3. Bob chama solve(Ethereum) com o preço do gas definido para 15 gwei
  4. Eve está observando o pool de transações para que a resposta seja enviada
  5. Eve vê a resposta de Bob e chama solve(Ethereum) com um preço de gas mais alto que Bob (100 gwei)
  6. A transação de Eve foi executada antes da transação de Bob, então Eve ganhou a recompensa de 10 Ether.

O que aconteceu?
As transações levam algum tempo antes de serem executadas.
As transações ainda não executadas são colocadas no pool de transações.
As transações com preço de gas mais alto geralmente são executadas primeiro.
Um invasor pode obter a resposta do pool de transações, enviar uma transação com um preço de gas mais alto para que sua transação seja executada antes das demais transações.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract FindThisHash {
bytes32 public constant hash =
0x564ccaf7594d66b1eaaea24fe01f0585bf52ee70852af4eac0cc4b04711cd0e2;
constructor() payable {}
function solve(string memory solution) public {
require(hash == keccak256(abi.encodePacked(solution)), "Resposta incorreta");
(bool sent, ) = msg.sender.call{value: 10 ether}("");
require(sent, "Failha ao enviar Ether");
}
}

Técnicas preventivas

  • use o esquema commit-reveal
  • use o modelo submarino de envio

Testar no Remix