Files
nexus/wiki/concepts/Checks-Effects-Interactions.md
2026-05-03 05:42:12 +08:00

82 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Checks-Effects-Interactions Pattern"
type: concept
tags: [blockchain, security, smart-contract, reentrancy, best-practices]
sources: [blockchain-security-auditor]
last_updated: 2026-05-30
---
## Aliases
- Checks-Effects-Interactions
- CEI Pattern
- Checks-Effects-Interactions Pattern
## Definition
Checks-Effects-InteractionsCEI检查-效果-交互)模式是智能合约安全编程的核心防御模式,用于防止重入攻击和其他逻辑漏洞。其核心原则是:**在执行任何外部调用之前,先完成所有的状态检查和状态更新**。
## Pattern
```
function withdraw() external {
// 1. CHECKS — 验证前置条件
require(balances[msg.sender] > 0, "No balance");
// 2. EFFECTS — 更新合约状态(在外部调用之前)
balances[msg.sender] = 0;
// 3. INTERACTIONS — 执行外部调用(最后一步)
(bool success,) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
```
## Why It Works
传统重入攻击利用的漏洞链:
```
外部调用ETH转账→ 攻击者receive()被触发
→ 攻击者 re-enter withdraw()
→ balances[msg.sender] 仍 > 0未清零
→ 重复提取资金
```
CEI 模式切断漏洞链:**状态在外部调用之前清零**,即使攻击者 re-enter条件检查阶段 `require(balances[msg.sender] > 0)` 已失败。
## Common Mistakes
### Wrong Order (Vulnerable)
```solidity
// VULNERABLE: 外部调用在状态更新之前
(bool success,) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0; // 攻击者可在此之前 re-enter
```
### Missing Update (Vulnerable)
```solidity
// VULNERABLE: 状态根本没有更新
require(balances[msg.sender] > 0);
(bool success,) = msg.sender.call{value: amount}("");
require(success);
// balances[msg.sender] = 0; ← 忘记更新!
```
### ERC-20 Transfer Before Update
```solidity
// VULNERABLE: ERC-20 transfer 触发外部调用
IERC20(token).transfer(msg.sender, amount); // 外部调用
balances[msg.sender] -= amount; // 状态更新太晚
```
## Relationship to Other Defenses
- **CEI is the primary defense** — should always be applied first
- **ReentrancyGuard is additional defense** — use when CEI is difficult to apply (complex logic, callbacks)
- CEI + ReentrancyGuard together provide defense in depth
## Connections
- [[Reentrancy]] ← prevents ← [[Checks-Effects-Interactions]]
- [[Blockchain-Security-Auditor]] ← enforces ← [[Checks-Effects-Interactions]]
- [[ReentrancyGuard]] ← supplements ← [[Checks-Effects-Interactions]]