Nesse artigo iremos aprender a como um contrato malicioso consegue manipular a data e hora do bloco de uma blockchain.
Vulnerabilidade
block.timestamp
pode ser manipulado por mineradores com as seguintes restrições:
- não pode ser carimbado com uma hora anterior ao seu antecessor
- não pode estar muito longe no futuro
Como funciona:
Roleta é um jogo onde você pode ganhar todo o Ether no contrato se você puder enviar uma transação em um momento específico.
Um jogador precisa enviar 10 Ether e ganha se o block.timestamp % 15 == 0
.
- Implante a Roleta com 10 Ether
- Eve executa um poderoso minerador que pode manipular o
timestamp
do bloco - Eve define o
block.timestamp
como um número no futuro que é divisível por 15 e encontra o hash do bloco de destino - O bloco de Eve é incluído com sucesso na cadeia, Eve ganha o jogo de Roleta
O que aconteceu?
Ao manipular o timestamp
do contrato da Roleta, Eve conseguiu definir um novo timestamp
para que sua resposta seja a correta e então ganhe os 10 Ether do jogo.
// SPDX-License-Identifier: MITpragma solidity ^0.8.13;contract Roulette {uint public pastBlockTime;constructor() payable {}function spin() external payable {require(msg.value == 10 ether); // deve enviar 10 ether para jogarrequire(block.timestamp != pastBlockTime); // apenas 1 transação por blocopastBlockTime = block.timestamp;if (block.timestamp % 15 == 0) {(bool sent, ) = msg.sender.call{value: address(this).balance}("");require(sent, "Falha ao enviar Ether");}}}
Técnicas preventivas
- Nunca use
block.timestamp
para uma fonte de data/hora e número aleatório