Token asks us to hack the basic token contract supplied. We start with 20 tokens and our objective is to get our hands on more.

We are given a hint that an odometer
might be of help so let’s start by looking it up.
An odometer is the mile tracker in your car that the numbers continue to go up as you drive, before they were all digital it was a real reel of numbers constantly rotating as the distance is traveled.

The odd thing about the old odometers is that they were only built to go up to 999,999.9 because each digit space is just 0-9 on a roller.
Therefore 999,999.9 will roll over to 000,000.0
But what does this have to do with our Token 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];
}
}
The odometer example and the old compiler version ^0.6.0
might give us the hint we need.
Like the odometer rolling over, an overflow/underflow occurs when the integer arithmetic produces a value outside the allotted bytes.
“In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bits – either larger than the maximum or lower than the minimum representable value.” from SWCRegistry-101 Description.
The reason the compiler may have given it away is that before 0.8.0 there were no errors thrown for an underflow or overflow.
Solidity < 0.8
Integers in Solidity overflow / underflow without any errorsSolidity >= 0.8
Arithmetic Overflow and Underflow
Default behaviour of Solidity 0.8 for overflow / underflow is to throw an error.
Before 0.8.0 it was widely known to use the SafeMath library to avoid these kinds of issues.
Back to the challenge… let’s get our new instance.

Open up Remix and paste our code, then manually change the compiler from the drop-down to 0.6.0
before you compile.

Go to the deploy/transact tab, select MetaMask for provider and scroll down to the At Address box, paste in your instance address.

Expand your deployed contract to see the functions, call totalSupply to see the total amount of tokens, paste your wallet address into balanceOf to see you have been given your 20 tokens.
Let’s break down the transfer function and solve this level.
function transfer(address _to, uint _value) public returns (bool) {
require(balances[msg.sender] - _value >= 0);
balances[msg.sender] -= _value;
balances[_to] += _value;
return true;
}
Our balance is 20 so we need to send more than 20 in order to cause an underflow.
Expand the transfer function in Remix and enter your instance address and the value to send, I put 22 and then transact.
Once it has been mined check the balanceOf your address and you should see a successful underflow.

We have successful made our balance a giant number of tokens through arithmetic underflow, all that’s left is to submit.

That’s it for level 5 Token, see you in the next one.
DAVE