在智能合约中,若在修改内部状态变量(如扣减余额)之前直接向外部合约转账,攻击者可利用合约的 fallback() 函数递归重新调用提现函数,导致合约金库被抽空(如著名的 The DAO 事件)。
一、遵循 Checks-Effects-Interactions 模式修复漏洞
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SecureVault {
mapping(address => uint256) public balances;
function withdraw() external {
uint256 amount = balances[msg.sender];
// 1. Checks 严格检查
require(amount > 0, "Insufficient funds");
// 2. Effects 立即修改内部状态
balances[msg.sender] = 0;
// 3. Interactions 最后执行外部交互调用
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
}