iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0

(Recovery) 倒楣鬼程式碼

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

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Recovery {

  //generate tokens
  function generateToken(string memory _name, uint256 _initialSupply) public {
    new SimpleToken(_name, msg.sender, _initialSupply);
  
  }
}

contract SimpleToken {

  using SafeMath for uint256;
  // public variables
  string public name;
  mapping (address => uint) public balances;

  // constructor
  constructor(string memory _name, address _creator, uint256 _initialSupply) public {
    name = _name;
    balances[_creator] = _initialSupply;
  }

  // collect ether in return for tokens
  receive() external payable {
    balances[msg.sender] = msg.value.mul(10);
  }

  // allow transfers of tokens
  function transfer(address _to, uint _amount) public { 
    require(balances[msg.sender] >= _amount);
    balances[msg.sender] = balances[msg.sender].sub(_amount);
    balances[_to] = _amount;
  }

  // clean up after ourselves
  function destroy(address payable _to) public {
    selfdestruct(_to);
  }
}

通關條件

玩家要將由 Recovery 產生的 Token 合約內的餘額清零才能通關

先備知識 - 以合約部署合約

new SimpleToken(_name, msg.sender, _initialSupply);

雖然題目關卡描述提過,合約的創建者丟失了合約地址,但我們從上述的指令知道,SimpleToken 合約是從 generateToken 這個合約裡面部署一個新的合約,並且也已知區塊鏈上的所有資料都會儲存在鏈上,因此照理講肯定是能夠找回丟失的地址的,那就接著從部署交易的紀錄去尋找丟失的合約地址吧。



這不就找到了嗎,哪裡消失了啊,ヽ(`Д´)ノ ヽ(`Д´)ノ ヽ(`Д´)ノ

程式碼

function destroy(address payable _to) public {
    selfdestruct(_to);
}

可以看到 SimpleToken 合約底下有個函數 destory,因此只要執行這個函數就能順利通關了,接著就進來通關的流程吧。

通關

請先在 remix 裡寫上以下的程式碼

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

contract SimpleToken {

  string public name;
  mapping (address => uint) public balances;

  constructor(string memory _name, address _creator, uint256 _initialSupply) {
    name = _name;
    balances[_creator] = _initialSupply;
  }

  receive() external payable {
    balances[msg.sender] = msg.value * 10;
  }

  function transfer(address _to, uint _amount) public { 
    require(balances[msg.sender] >= _amount);
    balances[msg.sender] = balances[msg.sender]-(_amount);
    balances[_to] = _amount;
  }

  function destroy(address payable _to) public {
    selfdestruct(_to);
  }
}

將部署環境改成部署至區塊鏈上

接著將合約地址填到下面的 At Address 後點擊

就發現我們可以操作那份消失的合約拉,直接執行 destory


٩(- ̮̮̃-̃)۶ ٩(- ̮̮̃-̃)۶ ٩(- ̮̮̃-̃)۶ ٩(- ̮̮̃-̃)۶


上一篇
Day 20 - Preservation
系列文
智能合約漏洞演練 - Ethernaut18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言