复习 - Week 11总结 (审计方法论 + Sui开发完成)
### 1. 审计方法论回顾
日期: 2026-06-19 方向: Solidity / Move / Sui 阶段: 第三阶段:安全审计 标签: #weekly-review #audit-methodology #sui-development #security-checklist #cross-chain
今日目标
| 类型 | 内容 |
|---|---|
| 学习 | 回顾并系统化本周学习的审计方法论和Sui开发技能 |
| 实操 | 整理所有Sui模块(Counter/NFT/Coin/Marketplace/Swap),评估开发技能掌握程度 |
| 产出 | 完整的审计方法论checklist + Sui开发技能评估 + EVM/Solana/Sui三链安全对比 |
核心概念
1. 审计方法论回顾
经过SC-DAY65和SC-DAY67两次手动审计练习,我们建立了一套系统化的审计方法论。以下是完整的审计流程总结。
完整审计流程(五阶段)
Stage 1: Scoping (范围界定)
├── 确认审计范围(哪些合约、哪些版本)
├── 理解项目背景和业务目标
├── 识别关键资产和用户角色
├── 列出已知的外部依赖
└── 评估合约复杂度,估算审计时间
Stage 2: Architecture Review (架构审查)
├── 画出合约间的调用关系图
├── 识别数据流和资金流
├── 检查继承关系和library使用
├── 评估整体设计模式的合理性
└── 标记需要重点关注的区域
Stage 3: Line-by-Line Review (逐行审查)
├── 按函数逐一检查(先external/public,后internal)
├── 对每个函数执行标准检查项
├── 标记所有可疑点(即使不确定是否是漏洞)
├── 检查状态变量的初始化和一致性
└── 验证事件是否完整和正确
Stage 4: Attack Scenario Analysis (攻击场景分析)
├── 对每个高风险函数构造攻击场景
├── 考虑多合约组合攻击
├── 考虑闪电贷辅助攻击
├── 考虑前端攻击(front-running/sandwich)
└── 考虑经济攻击(价格操纵/激励操纵)
Stage 5: Report Writing (报告编写)
├── 按严重性分级排序所有发现
├── 每个发现包含:描述/影响/复现步骤/修复建议
├── 编写审计摘要(scope/findings summary/recommendations)
├── 给出整体风险评估
└── 编写修复确认文档(如果有re-audit)
函数级审查Checklist
对每个 external / public 函数,逐项检查:
## 访问控制
[ ] 谁能调用这个函数?权限是否正确?
[ ] 是否缺少 onlyOwner/onlyAdmin 等修饰符?
[ ] 权限检查是否可以被绕过?
## 输入验证
[ ] 所有参数是否经过有效性检查?
[ ] 零值、最大值、负值(对于signed types)是否处理?
[ ] 地址参数是否检查了零地址?
[ ] 数组参数是否检查了长度?
## 状态变更
[ ] 是否遵循CEI模式(Checks-Effects-Interactions)?
[ ] 状态变更前是否完成了所有检查?
[ ] 外部调用是否在状态变更之后?
## 重入风险
[ ] 是否有外部调用(call/transfer/send/外部合约调用)?
[ ] 外部调用前状态是否已经更新?
[ ] 是否使用了 nonReentrant 修饰符(如果需要)?
## 数学运算
[ ] 是否可能溢出/下溢?(0.8.x中unchecked块要特别注意)
[ ] 除法是否可能除以零?
[ ] 精度是否足够?(先乘后除?PRECISION是否够大?)
[ ] 舍入方向是否对协议有利?
## 返回值
[ ] 外部调用的返回值是否检查?(特别是ERC20 transfer)
[ ] 函数返回值是否与文档/接口一致?
## 事件
[ ] 关键操作是否发出了事件?
[ ] 事件参数是否正确?(indexed参数、值)
[ ] 是否遗漏了某些转移的Transfer事件?
## Gas
[ ] 是否有无界循环(unbounded loop)?
[ ] 存储操作是否可以优化?
[ ] 是否可能因Gas耗尽而导致DoS?
2. 审计发现模式总结
从两次手动审计练习中提取的高频漏洞模式:
Token合约高频漏洞(来自SC-DAY65)
| 模式 | 说明 | 严重性 |
|---|---|---|
| 无限Mint权限 | Owner可无限铸造,中心化Rug Pull风险 | High |
| 无授权BurnFrom | 未检查allowance即可销毁他人Token | High |
| 费率无上限 | fee/tax参数无边界检查 | High |
| Ownership丢失 | transferOwnership缺少零地址检查 | Medium |
| Transfer事件缺失 | Fee部分的Transfer事件遗漏 | Low |
| Blacklist不完整 | 只检查sender不检查receiver | Low |
| Approve前端竞态 | 标准ERC20的已知问题 | Informational |
DeFi合约高频漏洞(来自SC-DAY67)
| 模式 | 说明 | 严重性 |
|---|---|---|
| 首存者攻击 | totalShares==0时份额计算可被操纵 | High |
| 奖励不足 | 承诺奖励超过实际可用余额 | High |
| Accounting偏差 | 内部记账与实际余额不一致 | High |
| Transfer返回值 | 未检查ERC20 transfer返回值 | Medium |
| 奖励覆盖 | 多次deposit时已累积奖励丢失 | Medium |
| 锁定期重置 | 追加deposit重置锁定期 | Medium |
Sui模块开发总览
所有已开发的Sui模块回顾
在整个学习过程中,我们开发了以下Sui Move模块:
Module 1: Counter(计数器)
功能: 创建、递增、递减、重置计数器
核心概念: Object模型基础、owned object、&mut引用
安全考虑: u64溢出检查、owner验证
// 核心结构
public struct Counter has key, store {
id: UID,
value: u64,
owner: address,
}
// 核心函数
public fun create(ctx: &mut TxContext): Counter
public fun increment(counter: &mut Counter)
public fun decrement(counter: &mut Counter)
public fun reset(counter: &mut Counter)
public fun increment_by(counter: &mut Counter, amount: u64)
public fun value(counter: &Counter): u64
掌握度评估: 完全掌握。理解Object创建、所有权、引用传递。
Module 2: SimpleNFT(NFT)
功能: 铸造NFT、转移、修改元数据、销毁
核心概念: Display标准、事件发出、所有权转移
安全考虑: 只有owner能修改、不可变数据用freeze
public struct SimpleNFT has key, store {
id: UID,
name: String,
description: String,
image_url: String,
creator: address,
}
public fun mint(name: String, desc: String, url: String, ctx: &mut TxContext): SimpleNFT
public fun transfer_nft(nft: SimpleNFT, recipient: address)
public fun update_description(nft: &mut SimpleNFT, new_desc: String)
public fun burn(nft: SimpleNFT)
掌握度评估: 完全掌握。理解NFT对象生命周期和Display标准。
Module 3: MomoCoin(自定义代币)
功能: 代币铸造、销毁、TreasuryCap管理
核心概念: sui::coin模块、One-Time Witness、TreasuryCap
安全考虑: TreasuryCap权限管理、supply追踪
public struct MOMO_COIN has drop {}
fun init(witness: MOMO_COIN, ctx: &mut TxContext) {
let (treasury_cap, metadata) = coin::create_currency(
witness, 9, b"MOMO", b"Momo Token", b"...", option::none(), ctx
);
transfer::public_transfer(treasury_cap, tx_context::sender(ctx));
transfer::public_freeze_object(metadata);
}
public fun mint(cap: &mut TreasuryCap<MOMO_COIN>, amount: u64, ctx: &mut TxContext): Coin<MOMO_COIN>
public fun burn(cap: &mut TreasuryCap<MOMO_COIN>, coin: Coin<MOMO_COIN>)
掌握度评估: 掌握。理解OTW模式和Coin框架。需要更多实操泛型Coin交互。
Module 4: Marketplace(NFT市场)
功能: 上架、下架、购买NFT
核心概念: shared object、dynamic fields、Coin支付
安全考虑: 价格操纵、只有卖家可下架、原子化交易
public struct Marketplace has key {
id: UID,
// listings stored as dynamic fields
}
public struct Listing has store {
seller: address,
price: u64,
nft_id: ID,
}
public fun list<T: key + store>(marketplace: &mut Marketplace, nft: T, price: u64, ctx: &mut TxContext)
public fun delist<T: key + store>(marketplace: &mut Marketplace, listing_id: ID, ctx: &mut TxContext): T
public fun buy<T: key + store>(marketplace: &mut Marketplace, listing_id: ID, payment: Coin<SUI>, ctx: &mut TxContext): T
掌握度评估: 良好。理解shared object和dynamic field的使用。复杂场景(拍卖、批量操作)需要更多练习。
Module 5: SimpleSwap(代币兑换)
功能: 创建流动性池、添加流动性、兑换
核心概念: 泛型编程、AMM公式、LP Token
安全考虑: 滑点保护、首添加者安全、K值守恒
public struct Pool<phantom X, phantom Y> has key {
id: UID,
reserve_x: Balance<X>,
reserve_y: Balance<Y>,
lp_supply: Supply<LP<X, Y>>,
}
public fun create_pool<X, Y>(ctx: &mut TxContext): Pool<X, Y>
public fun add_liquidity<X, Y>(pool: &mut Pool<X, Y>, x: Coin<X>, y: Coin<Y>, ctx: &mut TxContext): Coin<LP<X, Y>>
public fun swap_x_to_y<X, Y>(pool: &mut Pool<X, Y>, x_in: Coin<X>, min_y_out: u64, ctx: &mut TxContext): Coin<Y>
掌握度评估: 良好。理解AMM在Move中的实现。复杂数学(集中流动性、多hop路由)需要进一步学习。
Sui开发技能评估矩阵
| 技能领域 | 子技能 | 掌握度 | 备注 |
|---|---|---|---|
| 基础Object操作 | 创建/转移/删除 | 精通 | Counter/NFT练习充分 |
| Shared Object | 创建/访问/并发 | 良好 | Marketplace实践 |
| 泛型编程 | 泛型struct/function | 良好 | Swap模块中使用 |
| Coin框架 | 创建代币/TreasuryCap | 良好 | MomoCoin实践 |
| Dynamic Fields | 存/取/删 | 良好 | Marketplace中使用 |
| 事件系统 | 定义/发出/查询 | 掌握 | 所有模块都有事件 |
| 测试 | 单元测试/场景测试 | 良好 | Move test框架熟悉 |
| TypeScript SDK | 查询/交易/事件 | 良好 | SC-DAY68实践 |
| Move Prover | 基础spec编写 | 入门 | SC-DAY66学习概念 |
| 安全模式 | Witness/Capability/HP | 掌握 | 理解设计意图和使用 |
| PTB | 多操作组合交易 | 良好 | SDK实践 |
三链安全Checklist对比
综合安全检查清单:EVM + Solana + Sui
通用检查项(所有链)
## 权限控制
[ ] Admin/Owner权限是否有边界?
[ ] 权限转移是否安全(两步转移)?
[ ] 紧急暂停功能是否存在?
[ ] 多签保护关键操作?
## 输入验证
[ ] 所有用户输入是否验证?
[ ] 零值/最大值边界检查?
[ ] 地址/公钥有效性检查?
## 数学安全
[ ] 整数溢出/下溢保护?
[ ] 除法精度处理(先乘后除)?
[ ] 舍入方向对协议有利?
## 资金安全
[ ] 资金流向是否正确?
[ ] 是否存在资金被锁死的路径?
[ ] 紧急提取功能是否可用?
## 经济模型
[ ] 激励是否对齐?
[ ] 是否存在MEV/抢跑攻击面?
[ ] 预言机依赖是否安全?
EVM特有检查项
## 重入攻击
[ ] 外部调用前是否更新状态(CEI模式)?
[ ] 是否使用ReentrancyGuard?
[ ] 跨函数重入是否考虑?
[ ] 只读重入(view函数依赖的状态)是否安全?
## ERC20兼容
[ ] transfer返回值是否检查(SafeERC20)?
[ ] fee-on-transfer Token是否处理?
[ ] rebase Token是否处理?
[ ] ERC-777 hook重入是否防御?
## 代理/升级
[ ] 实现合约是否有初始化保护?
[ ] storage layout是否兼容?
[ ] selfdestruct风险?
[ ] delegatecall安全?
## Gas/DoS
[ ] 无界循环是否存在?
[ ] 大数组操作是否可能耗尽Gas?
[ ] 外部调用失败是否导致整体回滚?
## 闪电贷
[ ] 核心计算是否依赖瞬时余额?
[ ] 是否可在同一交易内deposit+withdraw获利?
[ ] 预言机价格是否可被闪电贷操纵?
## 签名相关
[ ] EIP-712签名是否正确实现?
[ ] 签名是否有nonce防重放?
[ ] 是否处理了签名延展性?
Solana特有检查项
## Account验证
[ ] 所有account是否验证了owner program?
[ ] PDA种子是否唯一且不可伪造?
[ ] signer是否正确验证?
[ ] 是否检查了account是否已初始化?
[ ] 关闭account时租金是否正确处理?
## CPI(跨程序调用)安全
[ ] CPI调用的目标program是否验证?
[ ] CPI中的signer seeds是否正确?
[ ] CPI返回数据是否正确处理?
## 数据安全
[ ] Account数据布局是否正确?
[ ] 反序列化是否安全?
[ ] 是否存在未初始化数据读取?
## Solana特有攻击
[ ] 是否防御了Type Confusion(同一account用于不同用途)?
[ ] 是否处理了Duplicate Account问题?
[ ] 交易是否可以被重放(缺少nonce/recent_blockhash验证)?
Sui/Move特有检查项
## Object安全
[ ] Object所有权模型是否正确?(owned vs shared vs immutable)
[ ] 创建的Object是否都被正确处理(transfer或delete)?
[ ] Shared Object的并发访问是否安全?
[ ] Dynamic Field的类型一致性?
## 能力(Ability)安全
[ ] struct的能力(key/store/copy/drop)是否最小化?
[ ] store能力是否会导致object被意外包装?
[ ] copy能力是否会导致资产被复制?(一般不给金融资产copy能力)
## Capability模式
[ ] TreasuryCap/AdminCap等capability是否正确管理?
[ ] Capability是否可以被转移(如果应该可以)?
[ ] One-Time Witness是否正确使用?
## Coin安全
[ ] Balance/Coin操作是否正确?
[ ] Coin分割/合并是否安全?
[ ] Supply追踪是否准确?
## Move特有
[ ] 是否利用了Move的类型安全(phantom types等)?
[ ] 是否有Hot Potato模式确保调用顺序?
[ ] 模块升级是否考虑了兼容性?
[ ] abort code是否有意义且有文档?
## 形式化验证
[ ] 核心不变量是否有spec?
[ ] 金融计算函数是否有ensures?
[ ] aborts_if条件是否完整?
三链安全特性对比
| 安全维度 | EVM (Solidity) | Solana (Rust/Anchor) | Sui (Move) |
|---|---|---|---|
| 重入防护 | 需手动防御(CEI/锁) | 无重入风险(单线程) | 无重入风险(对象引用) |
| 溢出保护 | 0.8.x内置/unchecked需注意 | Rust内置(debug)/wrapping | Move内置(所有算术) |
| 资源安全 | 无(可复制/丢弃ETH) | 有限(account需显式关闭) | 强(线性类型系统) |
| 权限模型 | Address检查(msg.sender) | Account验证+Signer | Capability Object |
| 升级机制 | Proxy模式(复杂) | Program升级(Authority) | Package升级(UpgradeCap) |
| 形式化验证 | 第三方工具(Certora等) | 有限工具支持 | Move Prover(原生) |
| 审计工具 | 最丰富(Slither/Mythril/...) | 中等(Soteria/Anchor verify) | 较少(生态较新) |
| 闪电贷风险 | 高(DeFi生态丰富) | 中(CPI组合) | 低(PTB模型不同) |
| Gas DoS | 高风险(Gas限制) | 低(compute units) | 低(存储退费) |
关键要点总结
审计方法论总结
-
系统化是关键:不要靠直觉审计,遵循checklist逐项检查。即使是资深审计员也会漏看"显而易见"的问题。
-
理解业务才能发现业务漏洞:50%以上的高危漏洞是业务逻辑问题(如份额计算错误、奖励分配不足),不是技术漏洞(如重入)。
-
攻击者思维:对每个函数问"如果我是攻击者"。考虑独立攻击、组合攻击(多函数串联)和外部辅助攻击(闪电贷)。
-
报告质量很重要:清晰的报告(描述、影响、复现、修复)比仅仅"找到bug"更有价值。好的报告能帮助开发者快速理解和修复问题。
Sui开发总结
-
Object思维是核心转变:从"合约存储"思维转变到"对象所有权"思维。这不仅影响代码写法,也影响产品设计。
-
PTB是Sui的差异化优势:充分利用可编程交易块,可以实现EVM做不到的用户体验(一次签名完成多步操作)。
-
Move的类型安全是双刃剑:编译器能捕获很多错误,但也让开发更"啰嗦"。习惯了之后,这是净正面的——编译通过意味着很多安全属性已经得到保证。
-
生态还在成长:Sui的工具链和审计资源比EVM少得多。这意味着早期进入的开发者/审计员有机会建立先发优势。
三链对比总结
- EVM:最成熟的生态,最多的工具和审计资源,但安全陷阱也最多
- Solana:高性能,Account验证是核心安全挑战,Anchor简化了很多安全检查
- Sui/Move:最安全的语言设计,类型系统消除了很多漏洞类别,但生态最年轻
常见误区
误区1:"熟悉了一条链的安全模型就可以审计所有链"
每条链的安全模型差异巨大。EVM的重入攻击在Solana和Sui上不存在,但Solana的Account Confusion和Sui的Shared Object并发问题在EVM上也不存在。跨链审计需要单独学习每条链的攻击面。
误区2:"审计Checklist可以替代审计经验"
Checklist是必要但不充分的。它确保你不遗漏基础检查项,但发现复杂的业务逻辑漏洞需要经验和直觉。Checklist是底线,不是天花板。
误区3:"Move语言安全就意味着Move合约安全"
Move消除了一些语言层面的漏洞,但业务逻辑漏洞、经济模型缺陷和权限设计问题在任何语言中都可能存在。不要因为"Move更安全"就放松警惕。
误区4:"前端集成不需要安全考虑"
前端是用户和链上合约之间的桥梁。常见的前端安全问题包括:
- 私钥存储不当(存在localStorage中)
- 交易参数被前端篡改
- 用户签署了不理解的交易
- Dry run显示的结果和实际执行不一致(TOCTOU问题)
面试关联
Q1: "你的智能合约审计方法论是什么?"
回答: 我遵循五阶段方法论:(1) Scoping——确定范围,理解业务目标和用户角色;(2) Architecture Review——画出合约关系图,识别数据流和资金流;(3) Line-by-Line Review——按标准checklist逐函数检查访问控制、输入验证、CEI模式、数学精度等;(4) Attack Scenario Analysis——构造攻击场景,考虑组合攻击和经济攻击;(5) Report Writing——按严重性分级输出结构化报告。
Q2: "EVM、Solana、Sui三条链的安全模型有什么核心区别?"
回答: 核心区别在三个维度:(1) 重入风险——EVM最高(需手动防御),Solana和Sui基本没有;(2) 资源安全——Move的线性类型最安全(资源不可复制/丢弃),Solidity没有这个保证;(3) 权限模型——EVM用address检查(msg.sender),Solana用Account Owner验证,Sui用Capability Object。每条链有自己独特的攻击面:EVM的闪电贷+重入,Solana的Account Confusion,Sui的Shared Object并发。
Q3: "如果让你负责一个多链DeFi协议的安全,你会怎么做?"
回答: 首先,每条链需要独立的安全审查,因为相同的业务逻辑在不同链上有不同的攻击面。其次,重点关注跨链桥接的安全——这是多链协议最脆弱的部分。具体步骤:(1) 每条链用该链的专用checklist审查;(2) 跨链消息验证逻辑单独审查;(3) 使用自动化工具扫描(EVM用Slither,Solana用Soteria)+ 手动审查业务逻辑;(4) 设置多签控制关键参数;(5) 部署监控系统,实时检测异常。
参考资源
| 资源 | 说明 |
|---|---|
| Solcurity Checklist | EVM安全检查清单 |
| Sealevel Attacks | Solana攻击案例集 |
| Sui Security Docs | Sui安全概念 |
| Solodit | 多链审计发现数据库 |
| Rekt News | 安全事件复盘 |
| DeFi Safety | DeFi协议安全评分 |
| Code4rena Reports | 社区审计报告 |
| Move Book | Move语言完整教程 |