# Ethernaut 14: Naught Coin

By [0xbanky](https://paragraph.com/@banky) · 2022-08-24

---

This is my solution for the 14th ethernaut challenge, Naught Coin

[https://ethernaut.openzeppelin.com/level/0x97E982a15FbB1C28F6B8ee971BEc15C78b3d263F](https://ethernaut.openzeppelin.com/level/0x97E982a15FbB1C28F6B8ee971BEc15C78b3d263F)

Investigation
=============

We have a smart contract which inherits the ERC20 implementation from OpenZeppelin

    import '@openzeppelin/contracts/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 = now + 10 * 365 days;
      uint256 public INITIAL_SUPPLY;
      address public player;
    
      constructor(address _player) 
      ERC20('NaughtCoin', '0x0')
      public {
        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(now > timeLock);
          _;
        } else {
         _;
        }
      } 
    }
    

It adds on some implementation detail which prevents the owner from transferring tokens out until it has been a year since the contract was created. The challenge here is to transfer the tokens out to some other address

Solution
========

I found that this was one of the easier ethernaut challenges. Looking through the [ERC20 implementation](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20) by OpenZeppelin, I found that there are additional ways to transfer tokens other than the `transfer` method which has been overriden above. Specifically, I was interested in the `transferFrom` method. The function signature looks like this

    transferFrom(address sender, address recipient, uint256 amount) → bool
    

This function uses the “allowance” mechanism from ERC20. All this means is that accounts can allow other accounts to spend tokens on their behalf. In my case, I decided I can just allow my own account to spend tokens, and then use `transferFrom` to send those tokens to another address.

    await contract.increaseAllowance(player, "1000000000000000000000000")
    await contract.transferFrom(player, "<other address>", "1000000000000000000000000")
    

And voila, the level is cracked.

What I learned
==============

1.  Overriding functions works to add custom authorization behaviour, but we have to be careful about all the mechanisms that we need to override
    
2.  I also learned about the full implementation of ERC20 from OpenZeppelin

---

*Originally published on [0xbanky](https://paragraph.com/@banky/ethernaut-14-naught-coin)*
