Ethernaut 题库闯关 #15 — Naught Coin

Ethernaut题库闯关连载的第15篇题解

今天这篇是Ethernaut 题库闯关连载的第15篇,难度等级:中等。

欢迎大家订阅专栏:Ethernaut 题库闯关,提升编码安全 Solidity代码能力。

挑战#15:Naught Coin

Naught Coin是一种ERC20代币,你持有所有这些代币。问题是,这些代币有10年的锁定期。本次挑战就是想办法把它们转移到另一个地址,让余额达到0,以便之后你可以自由的转移代币。

NaughtCoin代币的源码如下:

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

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 {
     _;
    }
  } 
} 

在查看解题思路之前,可以先自己想一想,自己会怎么做?

研究合约

让我们回顾一下合约的代码,合约是非常简单的。在constructor(构造函数)中,合约向player地址发行了 "1_000_000 "代币。

注意: 在 constructor 有一个双重事件触发。在 _mint执行后,合约 ”触发“ Transfer事件,而不知道OpenZeppelin _mint函数本身也会 触发 Transfer事件。

该合约通过在 "ERC20 "的实现中添加 lockTokens函数修改器来重载 "transfer "函数。让我们看看这个修改器的作用:


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

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Ethernaut CTF
Ethernaut CTF
信奉 CODE IS LAW.