#15 — Ethernaut Challenge 15 — Naught Coin

Rahul Pujari
2 min readJan 1, 2023

--

Objective:

  • Complete this level by getting your token balance to 0.

Understanding the Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import 'openzeppelin-contracts-08/token/ERC20/ERC20.sol';

contract NaughtCoin is ERC20 {

// string public constant name = 'NaughtCoin';
// string public constant symbol = '0x0';
// uint public constant decimals = 18;
uint public timeLock = block.timestamp + 10 * 365 days;
uint256 public INITIAL_SUPPLY;
address public player;

constructor(address _player)
ERC20('NaughtCoin', '0x0') {
player = _player;
INITIAL_SUPPLY = 1000000 * (10**uint256(decimals()));
// _totalSupply = INITIAL_SUPPLY;
// _balances[player] = INITIAL_SUPPLY;
_mint(player, INITIAL_SUPPLY);
emit Transfer(address(0), player, INITIAL_SUPPLY);
}

function transfer(address _to, uint256 _value) override public lockTokens returns(bool) {
super.transfer(_to, _value);
}

// Prevent the initial owner from transferring tokens until the timelock has passed
modifier lockTokens() {
if (msg.sender == player) {
require(block.timestamp > timeLock);
_;
} else {
_;
}
}
}

This code basically states that lockTokens modifier needs to be satisfied in order to transfer tokens. But, we will only be able to transfer them after a 10 year lockout period. But, they don’t know our superpower that we read the ERC20 token that we get from here. If you haven’t read it yet, I recommend you to check it out first. So, we will use other ERC20 functions to transfer from player to another account to make the player balance for tokens as 0.

How to hack this contract?

  1. Open the console and check the balance of the player(you) by typing in (await contract.balanceOf(player)).toString(). It should show some number like 1000000000000000000000000.
  2. Now, since we are inheriting this contract from ERC20, we can do await contract.approve(player, “1000000000000000000000000”) to approve ourselves from sending and spending this amount of tokens.
  3. Now run this command: await contract.transferFrom(player, “0x04b24656E4B114e4eF83f40a1161d1804e684D89”, “1000000000000000000000000”). This command enables us to transfer the tokens from the player(you)’s address to the destination address, which is a random ETH address.
  4. Now, upon running (await contract.balanceOf(player)).toString() we should get the balance as ‘0’ and now you can submit the instance. Well Done!

Congratulations on completing this level, more solutions to the remaining challenges will be coming up in my next blog posts, so make sure to follow and clap for more similar content!

Thanks for reading this far. I wish you all the best!

--

--

Rahul Pujari

I am a student in a university in India, I talk about web3 tech and blockchain because I am a web3 enthusiast!