[Ethernaut CTF] King

0xDave·2022년 10월 4일
0

Ethereum

목록 보기
30/112

소스코드


// 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;
  }
}

해결과제


The contract below represents a very simple game: 
whoever sends it an amount of ether that is larger than the current prize becomes the new king. 
On such an event, the overthrown king gets paid the new prize, making a bit of ether in the process! As ponzi as it gets xD

Such a fun game. Your goal is to break it.

When you submit the instance back to the level, the level is going to reclaim kingship. 
You will beat the level if you can avoid such a self proclamation.

해결과정


prize 보다 많은 이더를 보내고, 인스턴스를 제출할 때 kingship이 reclaim 되는 걸 방지하는 게 최종 목표인 것 같다. 일단 prize가 얼마인지부터 알아내보자.

0.001 초과로 보내면 되는 것 확인. 그런데 제출할 때 어떻게 방지해야 할 지 감이 안 잡힌다. 문제의 해답은 컨트랙트의 흐름에 있었다. 컨트랙트에 이더를 보내고 나면 내가 보낸 만큼의 이더를 이전 왕에게 보내고 내가 왕이 된다. 그리고 인스턴스를 제출할 때 다시 나(또는 해킹 컨트랙트)한테 prize 보다 더 큰 이더를 보낼 것이다. 그런데 이 때 해킹 컨트랙트가 이더를 받을 수 없는 상황이라면 왕위는 유지될 것이다. 다음부터는 컨트랙트의 흐름을 잘 파악하자.

profile
Just BUIDL :)

0개의 댓글