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 timestampdo bloco
- Eve define o block.timestampcomo 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.timestamppara uma fonte de data/hora e número aleatório