Ethernaut — Level 15 — Naught Coin

Zuhaib Mohammed
3 min readDec 11, 2021

I found this challenge to be pretty interesting and learnt things which I was previously unaware of. To understand better, lets understand what ERC20 standard is — it is basically a set of rules defined to declare the functions and methods accessible to the smart contract.

One can easily inherit the ERC20 standard into the smart contract using following syntax.

import ‘@openzeppelin/contracts/token/ERC20/ERC20.sol’; contract NaughtCoin is ERC20 {}

The standard also defines a set of mandatory and optional functions and fields. The mandatory ones include balanceOf , totalSupply , transfer , transferFrom , approve , and allowance and optional fields like the token name, symbol, and the number of decimal places.

The ERC20 Standard

The functions should be self explanatory but for the purpose of this challenge lets discuss two functions

transferFrom

It is kind of delegation call being made by the smart contract to transfer some value of tokens via “_from” to “_to” address and it returns true on success.

function transferFrom(address _from, address _to, uint _value) returns (bool success);

approve

For the transferFrom function to work, we need to first approve the delegation access via approve and pass in the number of tokens they can transfer.

function approve(address _spender, uint _value) returns (bool success);

Investigation

No need to jump to the remix IDE for this one. The chrome developer tools is good enough. Examining the code we see as part if the constructor, the following events take place

  1. Initialization of ERC20 and NaughtCoin constructor.
  2. Minting the number of tokens defined in INITIAL_SUPPLY.
  3. Transferring the token to the player’s address.

The goal is to transfer the tokens to a new address but the contract has a time lock of 10 years and we need to bypass that.

The Solution

To complete the challenge we need to just execute the “else” logic in the lockTokens modifier, where in the msg.sender and player address should be different but for the transfer to take place, the player address should have an approval for delegated transferFrom call. If it does not have the approval, this is how we grant it.

get the current balance of the player contract

We need a delegated approval to made to the player address, so that it can be able to transfer token. In an actual scenario, these address can be of a exchange or some trusted authority.

check the number of tokens the player has allowance access
approve the access of all the tokens to player
check the number of tokens the player has allowance access
transfer tokens to an arbitrary eth address
get the current balance of the player contract

The final balance is zero. That means we have successfully completed the challenge.

Thanks for Reading!

--

--