金库与 LP 的通胀攻击:第一笔存款与份额数学的隐患 图 1
金库与 LP 的通胀攻击:第一笔存款与份额数学的隐患 · 图 1

先说结论

金库合约用”份额”记账:你存入资产,得到代表所有权的份额,资产增长时份额对应价值上升。隐患藏在整数除法里:份额换算向下取整,让攻击者有机会用一笔精心构造的首存操纵”每份额对应多少资产”的读数,再在你下一次正常存取时把误差变成你的损失。这个类别的攻击有真实历史,补丁也是公开的——理解它,是使用任何金库产品前的安全常识。

攻击向量的三步推演

  1. 攻击者抢在所有人之前成为首存者,存入极小金额(比如 1 单位资产),得到 1 份额。此时比例 1:1。
  2. 攻击者直接向金库”捐赠”一大笔资产(不经存款函数,直接转账),不触发份额发行,但每份额对应的资产读数从 1 涨到巨大的 N。因为整数舍入规则,任何新存款者按份额计算时,向下取整会”蒸发”掉零头。
  3. 受害者按正常流程存入再赎回,损失的就是被取整吃掉的零头——单笔极小,攻击者却在同一笔交易里对大量受害者反复收割。 整条链路的致命点只有一个:首存份额发行与资产注入的顺序不受保护,让”每份额价值”这个内部读数可以在别人行动前被任意推高。完整拆解见 ERC4626 通胀攻击原理

协议侧的两类防御

  • 虚拟余额(virtual shares/offsets):合约内部给总资产与总份额各加一个常量再计算比例,使首存无法把读数推到极端——目前最常见的实现补丁。
  • 首存锁定:把首存份额铸给死地址或设最低首存门槛,让”捐赠改比例”在结构上无利可图。 两种防御都已出现在主流实现里,判断标准很简单:读合约或看审计报告有没有写明 virtual shares / minimum initial deposit 相关条款;一个都没有,就是把你暴露在这个已知类别面前。多资产凭证类新标准(ERC-7575,见 相关讲解)把记账进一步解耦,也改变了该攻击在特定结构下的成立条件。

用户侧三条判断

  1. 看接口而不是看宣传:金库用 EIP-4626 标准接口的,其实现细节(有没有虚拟余额)可以直接查合约或审计报告,这是十分钟能完成的尽调。
  2. 警惕”首存即高息”类活动:给首个大额存款者的专属激励设计,历史上恰好与攻击动机同构。
  3. 金库收益异常平稳、且说不清收益来源时,先怀疑记账与资产真实性,再谈策略(收益来源的判别框架见 收益到底从哪里来)。

定位这条风险

通胀攻击属于”实现细节风险”:协议没被盗、资产没出事,只是份额数学的坑没填。它恰好说明 DeFi 安全的重点常常不在故事而在接口——把”实现是否使用已知防御”加进你的金库检查清单,成本最低、回报最高。

风险提示

技术防御会随标准与实现演化,本文的判别方法基于公开的接口与审计实践,不保证覆盖所有变体。不构成投资建议。

五分钟完成的份额安全检查

不需要读完整份审计报告,三步就能把绝大多数金库筛一遍:第一步查该金库是否声明遵循 EIP-4626 接口(官网文档或部署页会写);第二步在其 GitHub 或审计公告里搜索关键词 virtual shares、virtual offset、minimum initial deposit,三者命中其一即说明实现知道并处理了这个已知类别;第三步看金库是否已运行过一段真实历史——有存量用户与多次存取记录的金库,首存攻击窗口早已关闭,新金库才需要前两步。三步都在几分钟内完成,判断结果可以直接标注到你的配置表上。若三步都过不去又确实想用,唯一合理的方式是极小额试跑一轮完整存取,用到账差额验证记账没有异常,再谈加仓。

(补充说明与前文同样只讨论机制与操作纪律,其中的假设数字均为原理示例而非实时数据,不构成投资建议。)