第22节:安全事故12-DOS攻击
调用外部合约可能永久失败导致本合约不能接受新的指令,例如当合约主动对另外一个合约转账,而被转账合约没有接受转账的函数时,转账失败,此时合约可能进入拒绝服务状态。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
contract Refunder {
address[] private refundAddresses;
mapping (address => uint) public refunds;
constructor() {
refundAddresses.push(0x79B483371E87d664cd39491b5F06250165e4b184);
refundAddresses.push(0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB);
}
// bad
function refundAll() public {
// arbitrary length iteration based on how many addresses participated
for(uint x; x < refundAddresses.length; x++) {
// doubly bad, now a single failure on send will hold up all funds
require(payable(refundAddresses[x]).send(refunds[refundAddresses[x]]));
}
}
}
存在问题:当合约向其中一个账号转账失败会导致所有转账全部失败。
解决方案:合约调用外部合约时可能出现的失败,合约需包含处理调用失败情况的代码,防止合约进入拒绝服务状态。