DEV Community

Cover image for Hack Solidity: Block Timestamp Manipulation
Kamil Polak
Kamil Polak

Posted on

Hack Solidity: Block Timestamp Manipulation

Timestamp provides information about the date and time in which the block is mined. When you go e.g. to the etherscan you can find a timestamp for each block that was mined.

timestamp solidity

Block timestamp can be manipulated by miners a then used to their advantage to attack a smart contract.

Let's go into details of how this could happen using the contract below.

contract Roulette {
    uint public pastBlockTime;

    constructor() payable {}

    function spin() external payable {
        require(msg.value == 5 ether); // player must send 5 ether to play
        require(block.timestamp != pastBlockTime); // only 1 transaction per block

        pastBlockTime = block.timestamp;
 // if the block.timestamp is divisible by 7 you win the Ether in the contract
        if (block.timestamp % 7 == 0) {
            (bool sent, ) = msg.sender.call{value: address(this).balance}("");
            require(sent, "Failed to send Ether");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

I created a simple game where a player can win all of the Ether in the contract if he submits a transaction at a specific time.

To join the game player need to send 5 ether. To play the game player call the spin function. If the block.timestamp is divisible by 7 player win all the Ether in the contract.

The miner that wants to win all of the Ethers can manipulate the contract. To do so he can:

  • call the spin function and submit 5 Ether to enter the game

  • submit a block.timestamp for the next block that is divisible by 7

How to prevent block timestamp attacks

There are two ways to prevent block timestamp attacks:

  • do not use block.timestamp in your contract

  • apply the 15-second rule which says that

If the scale of your time-dependent event can vary by 15 seconds and maintain integrity, it is safe to use a block.timestamp.

Sources

Discussion (0)