In challenge 5 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.
Let's first look at the given smart contract.
// 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];
}
}
This is a simple contract that allows to transfer and check the current balance of the contract. In the constructor, we can specify the total supply and assign it to a person who deployed the contract.
To hack this contract first you need to understand the concept of integer underflow and overflow. The overflow is a situation when uint (unsigned integer) reaches its byte size. Then the next element added will return the first variable element.
In the case of underflow, if you subtract 1 from a uint8 that is 0, it will change the value to 255.
Let me explain with an example. Note: The hardhat console library is necessary to log to the console in Remix.
pragma solidity ^ 0.6.0 ;
import "hardhat/console.sol";
contract Test {
constructor () public {
uint8 small = 0;
decrease--;
uint8 large = 255;
increase++;
console.log(small); // prints 255
console.log(large); // prints 0
}
}
If you run this code in Remix, be sure to use compiler version 0.6. As you can see we have a variable named decrease with value a 0. If we subtract 1 from that variable we end up with 255.
If you want to know more about integer underflow and overflow I have an additional article you can read: Integer Overflow and Underflow in Solidity
Let's move to our smart contract. To win this challenge we need to trigger an overflow or underflow. Keep in mind that we received 20 tokens.
All we need to do is:
To execute transfer
the function you need to take some real contract address. You can pick a one from Etherscan.io
There are two options. The first is to use OpenZeppelin's SafeMath library that automatically checks for overflows in all the mathematical operators. The second one is to use 0.8 Solidity version where overflow and underflow will cause a revert.
Also Published Here