@@ -15,6 +15,130 @@ timezone: UTC+8
1515## Notes
1616
1717<!-- Content_START -->
18+ # 2025-08-21
19+
20+ # ERC 4626
21+ 1 ) 规范全景(接口、事件、边界、实现自由度)
22+ - 核心概念
23+ - 资产 assets:Vault 所托管的底层 ERC‑20 代币(资产侧)。
24+ - 份额 shares:Vault 对用户的凭证(份额侧,本质上是一个 ERC‑20)。
25+ - 价格 price-per-share(pps):pps = totalAssets / totalSupply(注意舍入与 0 供给场景)。
26+ - 必选接口(关键函数族)
27+ - 资产与会计:asset()、totalAssets()
28+ - 转换:convertToShares(assets)、convertToAssets(shares)
29+ - 预览:previewDeposit、previewMint、previewWithdraw、previewRedeem
30+ - 上限:maxDeposit、maxMint、maxWithdraw、maxRedeem
31+ - 核心动作:deposit、mint、withdraw、redeem
32+ - 事件
33+ - Deposit(caller, owner, assets, shares)
34+ - Withdraw(caller, receiver, owner, assets, shares)
35+ - 另外还会有 ERC‑20 的 Transfer/Approval 事件(针对 shares)
36+ - 边界与约束
37+ - 预览函数不应修改状态,应与实际执行路径的舍入方向保持一致。
38+ - maxXxx 用于传达可行边界(额度/流动性/策略限制),做为路由与前端的“护栏”。
39+ - totalAssets 可为“真实余额 + 策略应计”,实现者有自由度,但必须与实际可提取价值相符。
40+ - 实现自由度与常见裁剪点(以库为参照)
41+ - 初始兑换率:当 totalSupply == 0 时的 shares↔assets 初始比率,多数实现默认 1:1,也可自定义(需清晰文档化)。
42+ - decimals:OZ 会尝试与底层资产 decimals 对齐;SM 默认 18,可自定义构造。
43+ - max 系列默认行为:通常默认无限或不限制,但生产上应结合风控/队列/策略流动性进行约束。
44+ - 策略/费用扩展:规范不含 fee 模型与策略接口,实现可在内部扩展(例如扣费铸份机制、harvest 钩子等)。
45+
46+ 2 ) 函数语义与舍入(数学关系、单调性、极端场景)
47+ - 数学关系(常见安全舍入约定)
48+ - shares = assets * totalSupply / totalAssets
49+ - assets = shares * totalAssets / totalSupply
50+ - 典型舍入方向(保持用户不吃亏/金库不吃亏的一致性)
51+ - previewDeposit(assets) → shares 使用向下取整 floor(避免过度发放 shares)
52+ - previewMint(shares) → assets 使用向上取整 ceil(确保付足资产才能铸得 shares)
53+ - previewWithdraw(assets) → shares 使用向上取整 ceil(确保烧足 shares 才能取出资产)
54+ - previewRedeem(shares) → assets 使用向下取整 floor(避免过度支付资产)
55+ - 单调性要求:资产与份额的双向转换应单调;totalAssets/totalSupply 的变化应一致反映在 preview 与实际执行上。
56+ - 与 preview/max/totalAssets 的一致性
57+ - previewXxx 与实际 deposit/mint/withdraw/redeem 的内部计算必须同向舍入,否则将被可利用为报价欺诈/拒绝服务。
58+ - maxXxx 应考虑流动性与限制:例如策略资金回流延迟、提款队列、额度上限与角色权限;并且与 revert 条件对应。
59+ - 极端场景建议
60+ - 流动性不足:maxWithdraw/maxRedeem 返回低值;withdraw/redeem 不应“部分成交”,而是通过 max 护栏引导上层分拆请求。
61+ - 0/1 最小份额:避免初始小额导致后续四舍五入锁尘。常见做法:由治理账户进行 seed deposit 或在首次 deposit 强制最小规模(并文档化)。
62+ - 精度差异:资产与份额 decimals 不同(如 6 vs 18),务必使用安全的乘除顺序与 mulDivDown/Up(SM)或 OZ 的 Math 库,避免中间溢出与精度丢失。
63+ - 非标准资产:fee‑on‑transfer 或 rebasing 资产导致“转账入账值 ≠ 请求值”,preview 必须与实际路径对齐(详见第 5 点)。
64+
65+ 3 ) 技术演进与实现对比
66+ - 变更点与已知坑(参考 2022–2025 )
67+ - 舍入策略趋于统一:社区已基本形成上述四条路径的“floor/ceil”约定,避免报价前后不一致。
68+ - preview 一致性意识增强:早期常见“preview 乐观,实际更保守”导致路由失败或可被博弈,现应确保纯函数逻辑与实际执行复用同一计算路径。
69+ - fee 计提与会计一致性:从“直接扣资产”逐步倾向“铸份到 feeRecipient”并保持老持有人不受损(抗稀释设计),并在事件中透明化。
70+ - rebasing 兼容:totalAssets 需以“可提取价值”为准,避免单看 balanceOf 或错误缓存;对 rebase 事件需有防御/校验。
71+ - max 函数安全护栏:从默认无限,演进为考虑提款队列、延时、角色开关、冻结模式(withdraw-only),以减少运行期风险。
72+ - 库实现对比(OZ v5 vs Solmate)
73+ - 安全性与完备度:OZ 偏安全保守,默认 SafeERC20、对 decimals 与 return 值更稳妥;SM 偏极简与 gas 优化,提供 mulDivDown/Up 等数学工具,要求使用者更自律。
74+ - 舍入实现:两者均提供 Down/Up 路径,但 OZ 更注重与 ERC‑20 生态的“非标准返回值/失败”适配;SM 更清晰地暴露向上/向下的选择权与成本。
75+ - decimals:OZ 经常对齐底层资产精度,降低集成复杂度;SM 常由开发者在构造函数中显式设定,灵活但需谨慎。
76+ - maxXxx 默认:两者默认都较宽松;生产应覆写以接入限额与风控逻辑(如管理侧限额、策略侧可用流动性、黑白名单)。
77+ - 扩展与组合:OZ 与上层 RBAC、Pausable、UUPS 升级模式整合度高;SM 与自定义策略/数学库/汇总器组合自由度高。
78+
79+ 4 ) 安全与不变式(攻击面、PoC 场景、缓解建议)
80+ - 攻击面与误用清单
81+ - preview 与实际不一致:路由/聚合器被“乐观报价”误导,用户或协议遭遇失败/滑点过大。
82+ - 防御:公用同一转换函数;测试覆盖“preview == 实际路径”断言;引入 max 护栏。
83+ - 份额稀释/膨胀:fee 计提或捐赠 donation 顺序不当,导致老持有人权益受损。
84+ - 防御:采用“给 feeRecipient 铸份”而非直接扣底层资产;在事件中透明化;加入上/下限与延时治理。
85+ - 闪电贷操纵 totalAssets/pps:瞬间存取/donate 干扰报价或清算。
86+ - 防御:对关键操作使用 TWAP 或延迟结算;策略侧快照;在路由侧加大滑点保护与多源报价。
87+ - 非标准 ERC‑20:fee‑on‑transfer/rebasing 导致会计错配与事件不一致。
88+ - 防御:以实际入账/出账为准更新会计;对 rebasing 采用“拉取式读取 + 上下限校验”;在 max/preview 中体现真实限制。
89+ - 授权与重入:shares 是 ERC‑20,若叠加 777/1363 或外部回调策略,需防重入与权限滥用。
90+ - 防御:ReentrancyGuard;pull 模式;外部调用最小化;严格的角色与延时,禁止在关键路径中可重入外部合约。
91+ - 事件与状态不一致:Deposit/Withdraw 与 ERC‑20 Transfer 次序或数量不一致,影响索引与合规审计。
92+ - 防御:测试断言事件与状态的一致性;失败即回滚。
93+ - permit/nonce:若 shares 实现了 EIP‑2612,必须保证 nonce 单调与域分隔正确。
94+ - 防御:覆盖 chainId 变化;deadline 检查;重放防护。
95+ - 关键不变式(建议纳入 invariant/fuzz)
96+ - 会计守恒:sum(userShares) == totalSupply;convert/preview 与 totalAssets/totalSupply 一致。
97+ - 价格单调:无外部注入/扣减时,pps 变化应可解释且与 fee/收益事件一致。
98+ - 事件一致性:Deposit/Withdraw 与 ERC‑20 Transfer 事件对应关系一致。
99+ - 预览一致:previewXxx 的结果与实际路径相同的舍入方向与边界。
100+ - 许可安全(可选):permit nonce 单调递增;签名域分隔不变。
101+
102+ 5 ) 生态应用与兼容性(DEX/借贷/聚合器/收益金库/LST/LRT/RWA)
103+ - DEX/路由
104+ - 一些路由支持 4626 包装/解包(wrap/unwrap)路径;若未原生支持,需事先 unwrap 成 assets 再交易。
105+ - 报价与滑点:务必使用 preview + max 护栏,并考虑 flash/donation 干扰导致的 pps 偏移。
106+ - 借贷/抵押
107+ - 抵押品定价:以 pps * assetPrice;若策略收益受延迟或预估,应采用 TWAP/预言机与安全边界。
108+ - 清算:赎回路径需有足够流动性;对提款队列或延时做风控参数与文档化。
109+ - 聚合器/收益金库(Vault-of-Vaults)
110+ - 组合多层 4626 容易产生舍入连锁误差;建议在上层进行批量化与对冲 rounding,或统一向上/向下策略。
111+ - 复杂 fee 模型叠加时,测试“多 hop + fee + rebase”的边界路径。
112+ - LST/LRT(质押衍生)
113+ - pps 单调上行是主预期;需防止 large donation/fee 事件造成短时跳变冲击聚合器。
114+ - 与共识层赎回/再质押周期联动,设置 maxWithdraw/maxRedeem 的时间窗约束。
115+ - RWA 托管
116+ - totalAssets 可能依赖托管清算周期/估值;必须在文档/事件中透明化估值延迟,避免赎回挤兑。
117+ - 非标准资产适配
118+ - fee‑on‑transfer:以实际入账金额记账;preview 应以“预估实际入账”为准(或在 UI/路由层设置安全折扣);事件使用实际金额。
119+ - rebasing:避免缓存资产余额;convert 基于最新 balanceOf;必要时加入“可提现上限”与“最小赎回单位”保护。
120+ - 税费/黑名单:maxXxx 应反映限制;失败路径清晰回滚与错误信息;必要时加入白名单与可暂停开关。
121+
122+ - 开发侧
123+ - 统一转换路径:将 convert/preview 与实际执行共享同一内部函数,确保一致性。
124+ - 舍入策略固定并文档化:按“deposit/redeem 向下;mint/withdraw 向上”实施,写入注释与 NatSpec。
125+ - maxXxx 接入风控:额度、队列、延时、策略流动性、黑白名单;对外披露治理参数。
126+ - 事件完整:Deposit/Withdraw 与 Transfer 顺序与数额一致;异常路径全回滚。
127+ - 资产兼容层:抽象一个 SafeAsset 适配层,处理 fee‑on‑transfer/非标准返回值;对 rebasing 做读取与上/下限校验。
128+ - 性能:缓存不可变的 decimals;使用安全的 mulDivDown/Up;避免重复外部调用;批量操作与 unchecked 安全使用。
129+ - 测试侧(Foundry 建议)
130+ - 单测:四条主路径 + preview/convert/max/totalAssets/decimals;事件对齐。
131+ - Fuzz:随机多用户多序列存取赎回;引入 donation、闪电贷扰动。
132+ - Invariant:会计守恒、事件一致、preview 一致、pps 单调/可解释。
133+ - 非标准资产模拟:fee‑on‑transfer、rebasing、拒收/延迟、返回值非标准。
134+ - 运维与监控
135+ - 指标:totalAssets、totalSupply、pps、maxXxx、失败率、fee 速率、harvest 间隔。
136+ - 告警:preview 与实际偏差阈值、pps 突变、rebase 异常、提款队列拥塞。
137+ - 应急:Pausable/Guardian;只提款模式;策略下线/切换流程;参数变更与延时治理。
138+ - 升级与权限(若用可升级模式)
139+ - 角色矩阵:Owner/Admin/Guardian/Strategy/Harvester;最小授权 + timelock。
140+ - 存储槽与 __ gap 稳定;升级回归测试覆盖 rounding/fee/preview 一致性;状态快照前后对账。
141+
18142# 2025-08-20
19143
20144一、定义与背景
0 commit comments