// 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];
}
}
solidity 0.8.0 버전 이후부터는 unchecked
를 사용하지 않으면 integer overflow/underflow가 발생할 경우 revert를 시키는데 이 문제에서는 0.6.0 버전이기 때문에 integer overflow/underflow가 발생할 수 있다는 것을 인지하여야 풀 수 있다.
이 문제는 초기 token을 20개 주는데 token의 개수를 늘려야하는 문제이다.
문제가 없어 보이는 것처럼 보이지만 transfer(address, uint256)
에서 integer underflow가 발생하여 balance[msg.sender]의 값을 증가시킬 수 있다.
uint256의 최대값을 만들기 위해 20-21이 되게하여 문제를 풀이하였다.
cast send --rpc-url $G_RPC --private-key $P_KEY 0xAE8D40E44a7F877E90162C186e09656402e47134 "transfer(address, uint256)" 0xAE8D40E44a7F877E90162C186e09656402e47134 21
transfer(address, 21)
실행