第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]]));
        }
    }
}

存在问题:当合约向其中一个账号转账失败会导致所有转账全部失败。

解决方案:合约调用外部合约时可能出现的失败,合约需包含处理调用失败情况的代码,防止合约进入拒绝服务状态。