返回 SC 笔记
SC Day 69

复习 - Week 11总结 (审计方法论 + Sui开发完成)

### 1. 审计方法论回顾

2026-06-19
第三阶段:安全审计
weekly-reviewaudit-methodologysui-developmentsecurity-checklistcross-chain

日期: 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即可销毁他人TokenHigh
费率无上限fee/tax参数无边界检查High
Ownership丢失transferOwnership缺少零地址检查Medium
Transfer事件缺失Fee部分的Transfer事件遗漏Low
Blacklist不完整只检查sender不检查receiverLow
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)/wrappingMove内置(所有算术)
资源安全无(可复制/丢弃ETH)有限(account需显式关闭)强(线性类型系统)
权限模型Address检查(msg.sender)Account验证+SignerCapability Object
升级机制Proxy模式(复杂)Program升级(Authority)Package升级(UpgradeCap)
形式化验证第三方工具(Certora等)有限工具支持Move Prover(原生)
审计工具最丰富(Slither/Mythril/...)中等(Soteria/Anchor verify)较少(生态较新)
闪电贷风险高(DeFi生态丰富)中(CPI组合)低(PTB模型不同)
Gas DoS高风险(Gas限制)低(compute units)低(存储退费)

关键要点总结

审计方法论总结

  1. 系统化是关键:不要靠直觉审计,遵循checklist逐项检查。即使是资深审计员也会漏看"显而易见"的问题。

  2. 理解业务才能发现业务漏洞:50%以上的高危漏洞是业务逻辑问题(如份额计算错误、奖励分配不足),不是技术漏洞(如重入)。

  3. 攻击者思维:对每个函数问"如果我是攻击者"。考虑独立攻击、组合攻击(多函数串联)和外部辅助攻击(闪电贷)。

  4. 报告质量很重要:清晰的报告(描述、影响、复现、修复)比仅仅"找到bug"更有价值。好的报告能帮助开发者快速理解和修复问题。

Sui开发总结

  1. Object思维是核心转变:从"合约存储"思维转变到"对象所有权"思维。这不仅影响代码写法,也影响产品设计。

  2. PTB是Sui的差异化优势:充分利用可编程交易块,可以实现EVM做不到的用户体验(一次签名完成多步操作)。

  3. Move的类型安全是双刃剑:编译器能捕获很多错误,但也让开发更"啰嗦"。习惯了之后,这是净正面的——编译通过意味着很多安全属性已经得到保证。

  4. 生态还在成长: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 ChecklistEVM安全检查清单
Sealevel AttacksSolana攻击案例集
Sui Security DocsSui安全概念
Solodit多链审计发现数据库
Rekt News安全事件复盘
DeFi SafetyDeFi协议安全评分
Code4rena Reports社区审计报告
Move BookMove语言完整教程