728x90
Description
The goal of this level is for you to hack the basic token contract below.
You are given 20 tokens to start with and you will beat the level if you somehow manage to get your hands on any additional tokens. Preferably a very large amount of tokens.
Things that might help:
- What is an odometer?
Code
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Token {
mapping(address => uint256) balances;
uint256 public totalSupply;
constructor(uint256 _initialSupply) public {
balances[msg.sender] = totalSupply = _initialSupply;
}
function transfer(address _to, uint256 _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 (uint256 balance) {
return balances[_owner];
}
}
Scenario
constructor()가 실행될 때 21000000가 total supply로 들어갔다.
나에겐 문제 조건대로 20개가 있다.
transfer()를 실행해서 내 토큰을 늘려야하는데, balances[msg.sender]도 나고, _to도 나이면 내 balance에서 빼고 다시 더하니까 결국 그대로 20개가 유지된다.
그런데 컴파일러 버전을 보니 0.6.0이다. 이 때는 컴파일러 자체에 over/underflow를 체크하는 함수가 내장되어 있지 않아 safeMath를 해주어야 하는데, 본 코드는 그렇지 않다. 따라서 overflow를 일으켜 토큰을 늘릴 수 있다. transfer()함수 실행 시 임의의 _to 주소에 20을 초과하는 토큰 개수를 보내면 내 balances에서 underflow가 발생하면서 max값이 내 토큰으로 들어오게 된다.
Exploit
728x90