# Ethernaut 5: Token **Published by:** [0xbanky](https://paragraph.com/@banky/) **Published on:** 2022-08-16 **URL:** https://paragraph.com/@banky/ethernaut-5-token ## Content My solution for the fifth ethernaut challenge: https://ethernaut.openzeppelin.com/level/0x63bE8347A617476CA461649897238A31835a32CEInvestigationWe have a Token contract that contains balances for address and a total supply.mapping(address => uint) balances; uint public totalSupply; We have a constructor which initializes a contract instance with a provided supply and gives that entire balance to the contract deployerconstructor(uint _initialSupply) public { balances[msg.sender] = totalSupply = _initialSupply; } There is a function which allows a transfer from the senders balance to the provided address. It simply checks that there is enough of a balance to be sent in the senders address, deducts the amount from the sender and assigns it to the to address.function transfer(address _to, uint _value) public returns (bool) { require(balances[msg.sender] - _value >= 0); balances[msg.sender] -= _value; balances[_to] += _value; return true; } Notably here, the computation is being done on uint values which can be overflowed. I tried out the transfer function using the Remix IDE and found that I was able to transfer 5 tokens to some other address. This worked since 5 was less than the amount in my wallet (initialized with 20 tokens).SolutionFirst, I tried to pass in a negative value to the function. My thinking is that the value would be treated as a uint during smart contract execution, which would be a very large number. This approach does not work though and I got an error from the EVMinstance.transfer("0x...", -10); // Error encoding arguments: Error: value out-of-bounds (argument=null, value="-5", code=INVALID_ARGUMENT, version=abi/5.5.0) So it seems like it wont work to just try passing in a negative number. Thinking about it some more, I noticed that on this linerequire(balances[msg.sender] - _value >= 0); An integer overflow can also be induced. ie. if I try to send more than I have in my wallet, balances[msg.sender] - _value will actually overflow and return some large value. I tried this outinstance.transfer("0x...", 25); instance.balanceOf("<my address>"); // uint256: balance 115792089237316195423570985008687907853269984665640564039457584007913129639931 My wallet now has several trillions of tokens 🤠What I learnedDuring the investigation, I found that this will actually not be an issue using a newer solidity version to compile our code (0.8.0 and above).Arithmetic operations revert on underflow and overflow. You can use unchecked { ... } to use the previous wrapping behaviour.From https://docs.soliditylang.org/en/latest/080-breaking-changes.htmlThis issue can be prevented on lower solidity versions with OpenZeppeling SafeMath. ## Publication Information - [0xbanky](https://paragraph.com/@banky/): Publication homepage - [All Posts](https://paragraph.com/@banky/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@banky): Subscribe to updates - [Twitter](https://twitter.com/0xbanky): Follow on Twitter