9 - King

breaking contract logic by not allowing to receive ether

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

contract King {

  address king;
  uint public prize;
  address public owner;

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

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

  function _king() public view returns (address) {
    return king;
  }
}

Goal of this level

  • Break the contract

What you should know before

  • How a contract can receive ether 1. payable fallback() function 2. receive() function -> see herearrow-up-right

Solution

chevron-rightKey to solve this problem πŸ”‘hashtag

king variable will never be updated if the previous king refuse to receive ether

We will send King contract the amount of value that is greater or equal to prize and do not implement any method to receive ether.

Then no matter how much the future player sends to King contract, value of king variable never be updated because the transaction will always revert when trying to send ether to previous king.

Use Remix IDE!

Deploy AttackKing contract with '1000000000000000' wei and call attack() function.

Done! 😎

Key Takeways

  • There is 2 ways of receiving ether. 1. payable fallback() 2. receive()

Last updated