智能合约审计之返回值未检查

文章前言

返回值调用验证问题多出现在和转币相关的智能合约中,故又称作静默失败发送或未经检查发送,在Solidity中存在transfer()、send()、call.value()等转币方法,都可以用于向某一地址发送Ether,其区别在于: 
  • transfer发送失败时会throw,并且进行状态回滚,只会传递2300gas供调用,防止重入攻击
  • send发送失败时会返回false,只会传递2300gas供调用,防止重入攻击
  • call.value发送失败时会返回false,传递所有可用gas进行调用(可通过传入gas_value参数进行限制),不能有效防止重入攻击。
这里的"未检查返回值的调用"主要指的就是没有检查send和call.value转币函数的返回值从而导致合约会继续执行后续代码,还可能由于Ether发送失败而导致意外的结果

演示示例

示例代码如下:
function withdraw(uint256 _amount) public {
  require(balances[msg.sender] >= _amount);
  balances[msg.sender] -= _amount;
  etherLeft -= _amount;
  msg.sender.send(_amount);
}

上面代码忘记检查send函数的返回值,如果Ether发送失败,由于没有自定义回滚机制,etherLeft将出现异常,从而导致msg.sender用户的币白白转丢,但是接受者的账户却没有收到任何代币。

防御措施

使用send和call.value进行转账操作时对返回值进行检查。

猜你喜欢

转载自blog.csdn.net/Fly_hps/article/details/118784329