ERC-4626 金库的四个预览函数:模拟值和到账值差在最后几位 图 1
ERC-4626 金库的四个预览函数:模拟值和到账值差在最后几位 · 图 1

用任何兼容 ERC-4626 的收益金库,你都会遇到同一个现象:点存款之前页面显示一个份额数,交易落链之后钱包里的份额数少了最后几个单位,却从来不会多。这不是故障,也不是暗收费,而是这套标准里预览函数和链上执行之间由整数舍入造成的固定关系。理解这层关系,能帮你把「页面向我承诺了什么」变成一个可以精确核对的问题。

ERC-4626 把金库操作拆成三组函数。第一组是真正改变状态的四个入口:depositmintwithdrawredeem,前两个入金、后两个出金,各自以底层资产或份额作为输入。第二组是四个预览函数:previewDepositpreviewMintpreviewWithdrawpreviewRedeem,它们是只读调用,告诉你如果现在执行会得到什么。第三组是换算与上限函数:convertToSharesconvertToAssets 给纯粹的份额与资产换算,maxDeposit 一类函数给出当前还能操作的数量边界。三组函数各司其职,误用其中一组去回答另一组的问题是差异感的第一大来源。

差异的核心在舍入方向。链上所有运算都是整数,换算成另一侧数量时必然要丢掉不足一个单位的部分。标准侧的处理原则是:预览值必须对用户足够保守,宁可少报、不能多报,这样交易才不会因为现实比承诺更好或更坏而翻车,实现普遍按这个方向落地。存币和取份额这两类以资产数量不确定收场的操作,给出的份额估值会向下取整;而以份额数量确定、资产数量浮动的操作,需要烧掉的份额估值会向上取整。落到体感上就是:用 deposit 存币,实际拿到的份额不会多于 previewDeposit 报给你的数;用 withdraw 固定取出资产数量,需要烧掉的份额不会少于 previewWithdraw 报给你的数。

第二种差异来自费用的记账位置。金库如果在入金或出金环节收费,标准的要求是预览函数必须把费用算进模拟值里,也就是说预览值应当等于你扣完费之后的真实结果,而不是税前数字再让你自己减。一个常见的核对方法是看事件日志:入金事件里记录的资产数量应当包含你实际支付的总手续费,出金事件里记录的份额数量也应当是含费烧掉的量。如果页面上的模拟值明显不含费,而链上结果含费,那差异就是前端展示口径的问题,而不是金库在偷吃。

第三种差异最简单也最容易被忽略:时间。预览函数模拟的是当前区块下的状态,你签名和交易被打包之间通常隔着几秒到几十秒,这期间利息计提、份额净值变动都会让真实结果和预览值偏离。利息按块累积的金库里,这个偏移的方向是确定的:入金者以略低的净值买到份额,出金者以略高的净值兑现,谁也不会占谁的便宜,但两边都不会精确等于预览值。

实操上你可以把核对动线固定成四步。第一步,区分你用的是换算函数还是预览函数,换算函数不含费用和上限逻辑,不能拿来核对到账数。第二步,记住方向:拿到的数量少于或等于预览值属正常,多出来才需要警惕是不是前端算错。第三步,出入金各查一次事件日志,把资产数量、份额数量和事件里的事件值对平。第四步,检查金库是否把小数位不同的资产做了换算处理,有些金库包装的底层资产和份额代币小数位不同,直接心算份额乘以汇率会差好几个数量级。

最后讲边界。这套标准和舍入约定只覆盖份额记账的精度与费用口径,不背书金库投的策略本身:预览值再精确,也不代表底层策略不会亏损、不会暂停提取、不会遭遇攻击。金库地址以官方文档与链上合约为准,具体金库的费用与净值口径以它的合约实现为准。本文只做机制说明,不构成投资建议。

ERC-4626 金库的四个预览函数:模拟值和到账值差在最后几位 图 2
ERC-4626 金库的四个预览函数:模拟值和到账值差在最后几位 · 图 2