v4-security-foundations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesev4 Hook Security Foundations
v4 Hook 安全基础
Security-first guide for building Uniswap v4 hooks. Hook vulnerabilities can drain user funds—understand these concepts before writing any hook code.
这是一份以安全为先的Uniswap v4 Hook开发指南。Hook漏洞可能导致用户资金被盗——在编写任何Hook代码前,请务必理解这些概念。
Threat Model
威胁模型
Before writing code, understand the v4 security context:
| Threat Area | Description | Mitigation |
|---|---|---|
| Caller Verification | Only | Verify |
| Sender Identity | | Use |
| Router Context | The | Implement router allowlisting |
| State Exposure | Hook state is readable during mid-transaction execution | Avoid storing sensitive data on-chain |
| Reentrancy Surface | External calls from hooks can enable reentrancy | Use reentrancy guards; minimize external calls |
编写代码前,请先了解v4的安全背景:
| 威胁领域 | 描述 | 缓解措施 |
|---|---|---|
| 调用者验证 | 仅 | 验证 |
| 发送者身份 | | 使用 |
| 路由器上下文 | | 实现路由器白名单机制 |
| 状态暴露 | Hook状态在交易执行过程中可被读取 | 避免在链上存储敏感数据 |
| 重入攻击面 | Hook发起的外部调用可能引发重入攻击 | 使用重入防护;尽量减少外部调用 |
Permission Flags Risk Matrix
权限标志风险矩阵
All 14 hook permissions with associated risk levels:
| Permission Flag | Risk Level | Description | Security Notes |
|---|---|---|---|
| LOW | Called before pool creation | Validate pool parameters |
| LOW | Called after pool creation | Safe for state initialization |
| MEDIUM | Before LP deposits | Can block legitimate LPs |
| LOW | After LP deposits | Safe for tracking/rewards |
| HIGH | Before LP withdrawals | Can trap user funds |
| LOW | After LP withdrawals | Safe for tracking |
| HIGH | Before swap execution | Can manipulate prices |
| MEDIUM | After swap execution | Can observe final state |
| LOW | Before donations | Access control only |
| LOW | After donations | Safe for tracking |
| CRITICAL | Returns custom swap amounts | NoOp attack vector |
| HIGH | Modifies post-swap amounts | Can extract value |
| HIGH | Modifies LP token amounts | Can shortchange LPs |
| HIGH | Modifies withdrawal amounts | Can steal funds |
所有14种Hook权限及其相关风险等级:
| 权限标志 | 风险等级 | 描述 | 安全注意事项 |
|---|---|---|---|
| 低 | 池创建前调用 | 验证池参数 |
| 低 | 池创建后调用 | 适合用于状态初始化 |
| 中 | 流动性存入前 | 可能阻止合法的流动性提供者操作 |
| 低 | 流动性存入后 | 适合用于跟踪/奖励发放 |
| 高 | 流动性提取前 | 可能锁定用户资金 |
| 低 | 流动性提取后 | 适合用于跟踪 |
| 高 | 交易执行前 | 可能操纵价格 |
| 中 | 交易执行后 | 可观察最终状态 |
| 低 | 捐赠前 | 仅做访问控制 |
| 低 | 捐赠后 | 适合用于跟踪 |
| 关键 | 返回自定义交易金额 | NoOp攻击向量 |
| 高 | 修改交易后金额 | 可能窃取资产 |
| 高 | 修改LP代币数量 | 可能少给流动性提供者发放代币 |
| 高 | 修改提取金额 | 可能窃取资金 |
Risk Thresholds
风险阈值
- LOW: Unlikely to cause fund loss
- MEDIUM: Requires careful implementation
- HIGH: Can cause fund loss if misimplemented
- CRITICAL: Can enable complete fund theft
- 低:不太可能造成资金损失
- 中:需要谨慎实现
- 高:若实现不当可能造成资金损失
- 关键:可能导致资金全部被盗
CRITICAL: NoOp Rug Pull Attack
关键风险:NoOp 地毯式攻击
The permission (bit 10) is the most dangerous hook permission. A malicious hook can:
BEFORE_SWAP_RETURNS_DELTA- Return a delta claiming it handled the entire swap
- PoolManager accepts this and settles the trade
- Hook keeps all input tokens without providing output
- User loses entire swap amount
BEFORE_SWAP_RETURNS_DELTA- 返回一个delta,声称已处理整个交易
- PoolManager接受该delta并完成交易结算
- Hook扣留所有输入代币,不提供输出
- 用户损失全部交易金额
Attack Pattern
攻击模式
solidity
// MALICIOUS - DO NOT USE
function beforeSwap(
address,
PoolKey calldata,
IPoolManager.SwapParams calldata params,
bytes calldata
) external override returns (bytes4, BeforeSwapDelta, uint24) {
// Claim to handle the swap but steal tokens
int128 amountSpecified = int128(params.amountSpecified);
BeforeSwapDelta delta = toBeforeSwapDelta(amountSpecified, 0);
return (BaseHook.beforeSwap.selector, delta, 0);
}solidity
// MALICIOUS - DO NOT USE
function beforeSwap(
address,
PoolKey calldata,
IPoolManager.SwapParams calldata params,
bytes calldata
) external override returns (bytes4, BeforeSwapDelta, uint24) {
// Claim to handle the swap but steal tokens
int128 amountSpecified = int128(params.amountSpecified);
BeforeSwapDelta delta = toBeforeSwapDelta(amountSpecified, 0);
return (BaseHook.beforeSwap.selector, delta, 0);
}Detection
检测方法
Before interacting with ANY hook that has :
beforeSwapReturnDelta: true- Audit the hook code - Verify legitimate use case
- Check ownership - Is it upgradeable? By whom?
- Verify track record - Has it been audited by reputable firms?
- Start small - Test with minimal amounts first
在与任何开启的Hook交互前:
beforeSwapReturnDelta: true- 审计Hook代码 - 验证其使用场景的合法性
- 检查所有权 - 它是否可升级?由谁控制?
- 验证过往记录 - 是否经过知名审计公司审计?
- 小额测试 - 先使用最小金额进行测试
Legitimate Uses
合法用途
NoOp patterns are valid for:
- Just-in-time liquidity (JIT)
- Custom AMM curves
- Intent-based trading systems
- RFQ/PMM integrations
But each requires careful implementation and audit.
NoOp模式的合法用途包括:
- 即时流动性(JIT)
- 自定义AMM曲线
- 基于意图的交易系统
- RFQ/PMM集成
但每种场景都需要谨慎实现并经过审计。
Delta Accounting Fundamentals
Delta 记账基础
v4 uses a credit/debit system through the PoolManager:
v4通过PoolManager使用借贷记账系统:
Core Invariant
核心不变量
text
For every transaction: sum(deltas) == 0The PoolManager tracks what each address owes or is owed. At transaction end, all debts must be settled.
text
For every transaction: sum(deltas) == 0PoolManager跟踪每个地址的欠款或应收款。交易结束时,所有债务必须结清。
Key Functions
核心函数
| Function | Purpose | Direction |
|---|---|---|
| Withdraw tokens from PoolManager | You receive tokens |
| Pay tokens to PoolManager | You send tokens |
| Update PoolManager balance tracking | Preparation for settle |
| 函数 | 用途 | 方向 |
|---|---|---|
| 从PoolManager提取代币 | 你接收代币 |
| 向PoolManager支付代币 | 你发送代币 |
| 更新PoolManager余额跟踪 | 为结算做准备 |
Settlement Pattern
结算模式
solidity
// Correct pattern: sync before settle
poolManager.sync(currency);
currency.transfer(address(poolManager), amount);
poolManager.settle(currency);solidity
// Correct pattern: sync before settle
poolManager.sync(currency);
currency.transfer(address(poolManager), amount);
poolManager.settle(currency);Common Mistakes
常见错误
- Forgetting sync: Settlement fails without sync
- Wrong order: Must sync → transfer → settle
- Partial settlement: Leaves transaction in invalid state
- Double settlement: Causes accounting errors
- 忘记sync:未执行sync会导致结算失败
- 顺序错误:必须遵循sync → transfer → settle的顺序
- 部分结算:会使交易处于无效状态
- 重复结算:会导致记账错误
Access Control Patterns
访问控制模式
PoolManager Verification
PoolManager 验证
Every hook callback MUST verify the caller:
solidity
modifier onlyPoolManager() {
require(msg.sender == address(poolManager), "Not PoolManager");
_;
}
function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
// Safe to proceed
}每个Hook回调必须验证调用者:
solidity
modifier onlyPoolManager() {
require(msg.sender == address(poolManager), "Not PoolManager");
_;
}
function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
// Safe to proceed
}Why This Matters
为什么这很重要
Without this check:
- Anyone can call hook functions directly
- Attackers can manipulate hook state
- Funds can be drained through fake callbacks
如果没有此检查:
- 任何人都可以直接调用Hook函数
- 攻击者可操纵Hook状态
- 可通过伪造回调窃取资金
Router Verification Patterns
路由器验证模式
The parameter is the router, not the end user. For hooks that need user identity:
sendersenderAllowlisting Pattern
白名单模式
solidity
mapping(address => bool) public allowedRouters;
function beforeSwap(
address sender, // This is the router
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
require(allowedRouters[sender], "Router not allowed");
// Proceed with swap
}solidity
mapping(address => bool) public allowedRouters;
function beforeSwap(
address sender, // This is the router
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
require(allowedRouters[sender], "Router not allowed");
// Proceed with swap
}User Identity via hookData
通过hookData获取用户身份
solidity
function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
// Decode user address from hookData (router must include it)
address user = abi.decode(hookData, (address));
// CAUTION: Router must be trusted to provide accurate user
}solidity
function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external override onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) {
// Decode user address from hookData (router must include it)
address user = abi.decode(hookData, (address));
// CAUTION: Router must be trusted to provide accurate user
}msg.sender Trap
msg.sender 陷阱
solidity
// WRONG - msg.sender is always PoolManager in hooks
function beforeSwap(...) external {
require(msg.sender == someUser); // Always fails or wrong
}
// CORRECT - Use sender parameter
function beforeSwap(address sender, ...) external {
require(allowedRouters[sender], "Invalid router");
}solidity
// WRONG - msg.sender is always PoolManager in hooks
function beforeSwap(...) external {
require(msg.sender == someUser); // Always fails or wrong
}
// CORRECT - Use sender parameter
function beforeSwap(address sender, ...) external {
require(allowedRouters[sender], "Invalid router");
}Token Handling Hazards
代币处理风险
Not all tokens behave like standard ERC-20s:
| Token Type | Hazard | Mitigation |
|---|---|---|
| Fee-on-transfer | Received amount < sent amount | Measure actual balance changes |
| Rebasing | Balance changes without transfers | Avoid storing raw balances |
| ERC-777 | Transfer callbacks enable reentrancy | Use reentrancy guards |
| Pausable | Transfers can be blocked | Handle transfer failures gracefully |
| Blocklist | Specific addresses blocked | Test with production addresses |
| Low decimals | Precision loss in calculations | Use appropriate scaling |
并非所有代币都表现得像标准ERC-20:
| 代币类型 | 风险 | 缓解措施 |
|---|---|---|
| 手续费代币 | 实际收到的金额 < 发送金额 | 测量实际余额变化 |
| 重基代币 | 无需转账即可改变余额 | 避免存储原始余额 |
| ERC-777 | 转账回调可能引发重入攻击 | 使用重入防护 |
| Pausable代币 | 转账可能被阻止 | 优雅处理转账失败情况 |
| 黑名单代币 | 特定地址被禁止转账 | 使用生产地址进行测试 |
| 低精度代币 | 计算时可能丢失精度 | 使用适当的缩放比例 |
Safe Balance Check Pattern
安全余额检查模式
solidity
function safeTransferIn(
IERC20 token,
address from,
uint256 amount
) internal returns (uint256 received) {
uint256 balanceBefore = token.balanceOf(address(this));
token.safeTransferFrom(from, address(this), amount);
received = token.balanceOf(address(this)) - balanceBefore;
}solidity
function safeTransferIn(
IERC20 token,
address from,
uint256 amount
) internal returns (uint256 received) {
uint256 balanceBefore = token.balanceOf(address(this));
token.safeTransferFrom(from, address(this), amount);
received = token.balanceOf(address(this)) - balanceBefore;
}Base Hook Template
基础Hook模板
Start with all permissions disabled. Enable only what you need:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {BaseHook} from "v4-periphery/src/base/hooks/BaseHook.sol";
import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol";
import {PoolKey} from "v4-core/src/types/PoolKey.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "v4-core/src/types/BeforeSwapDelta.sol";
contract SecureHook is BaseHook {
constructor(IPoolManager _poolManager) BaseHook(_poolManager) {}
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: false,
afterInitialize: false,
beforeAddLiquidity: false,
afterAddLiquidity: false,
beforeRemoveLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: false, // Enable only if needed
afterSwap: false, // Enable only if needed
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false, // DANGER: NoOp attack vector
afterSwapReturnDelta: false, // DANGER: Can extract value
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}
// Implement only the callbacks you enabled above
}See references/base-hook-template.md for a complete implementation template.
从禁用所有权限开始,仅启用你需要的权限:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {BaseHook} from "v4-periphery/src/base/hooks/BaseHook.sol";
import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol";
import {PoolKey} from "v4-core/src/types/PoolKey.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "v4-core/src/types/BeforeSwapDelta.sol";
contract SecureHook is BaseHook {
constructor(IPoolManager _poolManager) BaseHook(_poolManager) {}
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: false,
afterInitialize: false,
beforeAddLiquidity: false,
afterAddLiquidity: false,
beforeRemoveLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: false, // Enable only if needed
afterSwap: false, // Enable only if needed
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false, // DANGER: NoOp attack vector
afterSwapReturnDelta: false, // DANGER: Can extract value
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}
// Implement only the callbacks you enabled above
}完整的实现模板请参考references/base-hook-template.md。
Security Checklist
安全检查清单
Before deploying any hook:
| # | Check | Status |
|---|---|---|
| 1 | All hook callbacks verify | [ ] |
| 2 | Router allowlisting implemented if needed | [ ] |
| 3 | No unbounded loops that can cause OOG | [ ] |
| 4 | Reentrancy guards on external calls | [ ] |
| 5 | Delta accounting sums to zero | [ ] |
| 6 | Fee-on-transfer tokens handled | [ ] |
| 7 | No hardcoded addresses | [ ] |
| 8 | Slippage parameters respected | [ ] |
| 9 | No sensitive data stored on-chain | [ ] |
| 10 | Upgrade mechanisms secured (if applicable) | [ ] |
| 11 | | [ ] |
| 12 | Fuzz testing completed | [ ] |
| 13 | Invariant testing completed | [ ] |
部署任何Hook前,请完成以下检查:
| # | 检查项 | 状态 |
|---|---|---|
| 1 | 所有Hook回调都验证 | [ ] |
| 2 | 已实现路由器白名单(若需要) | [ ] |
| 3 | 无可能导致OOG的无界循环 | [ ] |
| 4 | 外部调用已添加重入防护 | [ ] |
| 5 | Delta记账总和为零 | [ ] |
| 6 | 已处理手续费代币 | [ ] |
| 7 | 无硬编码地址 | [ ] |
| 8 | 已遵守滑点参数 | [ ] |
| 9 | 无敏感数据存储在链上 | [ ] |
| 10 | 升级机制已做安全防护(若适用) | [ ] |
| 11 | 若启用 | [ ] |
| 12 | 已完成模糊测试 | [ ] |
| 13 | 已完成不变量测试 | [ ] |
Gas Budget Guidelines
燃气预算指南
Hook callbacks execute inside the PoolManager's transaction context. Excessive gas consumption can make swaps revert or become economically unviable.
Hook回调在PoolManager的交易上下文中执行,过高的燃气消耗可能导致交易回滚或在经济上不可行。
Gas Budgets by Callback
各回调的燃气预算
| Callback | Target Budget | Hard Ceiling | Notes |
|---|---|---|---|
| < 50,000 gas | 150,000 gas | Runs on every swap; keep lean |
| < 30,000 gas | 100,000 gas | Analytics/tracking only |
| < 50,000 gas | 200,000 gas | May include access control |
| < 30,000 gas | 100,000 gas | Reward tracking |
| < 50,000 gas | 200,000 gas | Lock validation |
| < 30,000 gas | 100,000 gas | Tracking/accounting |
| Callbacks with external calls | < 100,000 gas | 300,000 gas | External DEX routing, oracles |
| 回调 | 目标预算 | 硬上限 | 说明 |
|---|---|---|---|
| < 50,000 gas | 150,000 gas | 每次交易都会执行;尽量精简 |
| < 30,000 gas | 100,000 gas | 仅用于分析/跟踪 |
| < 50,000 gas | 200,000 gas | 可能包含访问控制 |
| < 30,000 gas | 100,000 gas | 奖励跟踪 |
| < 50,000 gas | 200,000 gas | 锁定验证 |
| < 30,000 gas | 100,000 gas | 跟踪/记账 |
| 带外部调用的回调 | < 100,000 gas | 300,000 gas | 外部DEX路由、预言机 |
Common Gas Pitfalls
常见燃气陷阱
- Unbounded loops: Iterating over dynamic arrays (e.g., all active positions) can exceed block gas limits. Cap array sizes or use pagination.
- SSTORE in hot paths: Each new storage slot costs ~20,000 gas. Prefer transient storage (/
tstore) for data that doesn't persist beyond the transaction. Requires Solidity >= 0.8.24 with EVM target set totloador later.cancun - External calls: Each cross-contract call adds ~2,600 gas base cost plus the callee's execution. Batch calls where possible.
- String operations: Avoid manipulation in callbacks; use
stringfor identifiers.bytes32 - Redundant reads: Cache calls — repeated
poolManagerorgetSlot0()reads cost gas each time.getLiquidity()
- 无界循环:遍历动态数组(如所有活跃仓位)可能超出区块燃气限制。限制数组大小或使用分页。
- 热点路径中的SSTORE:每个新存储槽消耗约20,000 gas。对于不需要跨交易持久化的数据,优先使用临时存储(/
tstore)。要求Solidity >= 0.8.24,且EVM目标设置为tload或更高版本。cancun - 外部调用:每次跨合约调用会增加约2,600 gas的基础成本加上被调用者的执行成本。尽可能批量调用。
- 字符串操作:避免在回调中进行操作;使用
string作为标识符。bytes32 - 冗余读取:缓存调用——重复调用
poolManager或getSlot0()每次都会消耗燃气。getLiquidity()
Measuring Gas
测量燃气消耗
bash
undefinedbash
undefinedProfile a specific hook callback with Foundry
Profile a specific hook callback with Foundry
forge test --match-test test_beforeSwapGas --gas-report
forge test --match-test test_beforeSwapGas --gas-report
Snapshot gas usage across all tests
Snapshot gas usage across all tests
forge snapshot --match-contract MyHookTest
---forge snapshot --match-contract MyHookTest
---Risk Scoring System
风险评分系统
Calculate your hook's risk score (0-33):
| Category | Points | Criteria |
|---|---|---|
| Permissions | 0-14 | Sum of enabled permission risk levels |
| External Calls | 0-5 | Number and type of external interactions |
| State Complexity | 0-5 | Amount of mutable state |
| Upgrade Mechanism | 0-5 | Proxy, admin functions, etc. |
| Token Handling | 0-4 | Non-standard token support |
计算你的Hook风险评分(0-33):
| 类别 | 分值 | 标准 |
|---|---|---|
| 权限 | 0-14 | 已启用权限的风险等级总和 |
| 外部调用 | 0-5 | 外部交互的数量和类型 |
| 状态复杂度 | 0-5 | 可变状态的数量 |
| 升级机制 | 0-5 | 代理、管理员函数等。 |
| 代币处理 | 0-4 | 非标准代币支持 |
Audit Tier Recommendations
审计等级建议
| Score | Risk Level | Recommendation |
|---|---|---|
| 0-5 | Low | Self-audit + peer review |
| 6-12 | Medium | Professional audit recommended |
| 13-20 | High | Professional audit required |
| 21-33 | Critical | Multiple audits required |
| 评分 | 风险等级 | 建议 |
|---|---|---|
| 0-5 | 低 | 自审计 + 同行评审 |
| 6-12 | 中 | 建议进行专业审计 |
| 13-20 | 高 | 必须进行专业审计 |
| 21-33 | 关键 | 需要多次审计 |
Absolute Prohibitions
绝对禁止事项
Never do these things in a hook:
- Never trust for user identity - It's always PoolManager
msg.sender - Never enable without understanding NoOp attacks
beforeSwapReturnDelta - Never store passwords, keys, or PII on-chain
- Never use for ETH - Use
transfer()call{value:}("") - Never assume token decimals - Always query the token
- Never use for randomness
block.timestamp - Never hardcode gas limits in calls
- Never ignore return values from external calls
- Never use for authorization - It's a phishing vector; malicious contracts can relay calls with the original user's
tx.origintx.origin
在Hook中绝对不要做以下事情:
- 永远不要信任作为用户身份 - 它始终是PoolManager
msg.sender - 永远不要在未理解NoOp攻击的情况下启用
beforeSwapReturnDelta - 永远不要在链上存储密码、密钥或PII
- 永远不要使用发送ETH - 使用
transfer()call{value:}("") - 永远不要假设代币的小数位数 - 始终查询代币的小数位数
- 永远不要使用生成随机数
block.timestamp - 永远不要在调用中硬编码燃气限制
- 永远不要忽略外部调用的返回值
- 永远不要使用进行授权 - 这是钓鱼攻击的载体;恶意合约可以通过原始用户的
tx.origin中继调用tx.origin
Pre-Deployment Audit Checklist
部署前审计检查清单
| # | Item | Required For |
|---|---|---|
| 1 | Code review by security-focused developer | All hooks |
| 2 | Unit tests for all callbacks | All hooks |
| 3 | Fuzz testing with Foundry | All hooks |
| 4 | Invariant testing | Hooks with delta returns |
| 5 | Fork testing on mainnet | All hooks |
| 6 | Gas profiling | All hooks |
| 7 | Formal verification | Critical hooks |
| 8 | Slither/Mythril analysis | All hooks |
| 9 | External audit | Medium+ risk hooks |
| 10 | Bug bounty program | High+ risk hooks |
| 11 | Monitoring/alerting setup | All production hooks |
See references/audit-checklist.md for detailed audit requirements.
| # | 项 | 适用场景 |
|---|---|---|
| 1 | 由专注安全的开发者进行代码审查 | 所有Hook |
| 2 | 为所有回调编写单元测试 | 所有Hook |
| 3 | 使用Foundry进行模糊测试 | 所有Hook |
| 4 | 不变量测试 | 带有delta返回的Hook |
| 5 | 在主网分叉上进行测试 | 所有Hook |
| 6 | 燃气分析 | 所有Hook |
| 7 | 形式化验证 | 关键Hook |
| 8 | Slither/Mythril分析 | 所有Hook |
| 9 | 外部审计 | 中高风险Hook |
| 10 | 漏洞赏金计划 | 高风险Hook |
| 11 | 监控/告警设置 | 所有生产环境Hook |
详细的审计要求请参考references/audit-checklist.md。
Production Hook References
生产环境Hook参考
Learn from audited, production hooks:
| Project | Description | Notable Security Features |
|---|---|---|
| Flaunch | Token launch platform | Multi-sig admin, timelocks |
| EulerSwap | Lending integration | Isolated risk per market |
| Zaha TWAMM | Time-weighted AMM | Gradual execution reduces MEV |
| Bunni | LP management | Concentrated liquidity guards |
从已通过审计的生产环境Hook中学习:
| 项目 | 描述 | 值得注意的安全特性 |
|---|---|---|
| Flaunch | 代币发行平台 | 多签管理、时间锁 |
| EulerSwap | 借贷集成 | 按市场隔离风险 |
| Zaha TWAMM | 时间加权AMM | 渐进式执行减少MEV |
| Bunni | LP管理 | 集中式流动性防护 |
External Resources
外部资源
Official Documentation
官方文档
Security Resources
安全资源
Community
社区
- v4-hooks-skill by @igoryuzo - Community skill that inspired this guide
- v4hooks.dev - Community hook resources
- v4-hooks-skill by @igoryuzo - 启发本指南的社区技能
- v4hooks.dev - 社区Hook资源平台
Additional References
额外参考
- Base Hook Template - Complete implementation starter
- Vulnerabilities Catalog - Common patterns and mitigations
- Audit Checklist - Detailed pre-deployment checklist
- Base Hook模板 - 完整的实现入门模板
- 漏洞目录 - 常见模式及缓解措施
- 审计检查清单 - 详细的部署前检查清单