
先把开始、持续时间和终点对应起来
查看区块链代币解锁资料时,一条标有日期的曲线还需要对应具体实现。这里采用OpenZeppelin Contracts 5.4.0的VestingWallet和VestingWalletCliff源码。它们是可用于构建应用的组件,不证明某个项目采用相同公式。下文的归属仅指该合约按计划计算的数量。
基础钱包保存开始时间与持续秒数,终点等于二者相加。默认公式在开始前返回零,在终点及之后返回全部历史分配量;处于中间时,以分配量乘已过时间,再除持续时间。持续时间为零时,开始时点也就是终点,代码进入对应分支,不是在中间公式中实际执行除以零。
悬崖期不把整条曲线重新起算
Cliff扩展把悬崖时点设置为原开始时间加悬崖秒数,并要求悬崖持续时间不大于总持续时间。在悬崖到来之前,它直接返回零;到来后调用继承的归属公式。因此,在未另行改写公式的组合里,悬崖时点限制首次归属,却没有把基础钱包的开始时间替换成这个时点。
设一个完全虚构的算例:总量一百个最小记账单位,持续十秒,悬崖四秒。开始后三秒仍返回零,恰好四秒时按原起点已过四秒计算,得到四十;五秒时为五十。不能画成第四秒从零开始、再用新的十秒慢慢增长。这个短时算例只用于读公式,不是实际项目的释放计划。

中途加入的资金仍跟随原安排
源码计算代币的历史分配量时,采用钱包当前余额加已经释放的数量。文档也明确,后来转入的资产按从计划开始时就被锁入来处理。因此,不能只依据转入发生在第五秒,就给这笔资金另画一条第五秒才开始的新曲线;该实现没有因此自动建立独立计划。
继续假设普通余额行为、此前没有释放或其他变动:上述一百单位在第五秒又收到一百,总量成为二百,此刻按一半进度算出一百。如果仍用原来的一百作为总量,只会得到五十。这里比较同一时点转入前后的计算基数,不表示已经完成实际转账;自动调整余额的代币等特殊情形须另按实现分析。
整数结果还要按最小单位理解
Solidity 0.8.24的类型文档说明,整数除法仍返回整数,并向零方向舍入;对这里的非负数量,就是舍去不足一个最小单位的部分。另设七单位、十秒持续时间,在适用线性分支的第四秒,按整数运算得到二,而不是二点八。这个语言规则不同于只含数字字面量时可保留有理数的计算。
归档曲线时应保留代码版本、是否改写公式、开始与悬崖时点、持续秒数、查询时点和计算使用的历史总量,再注明最小单位与展示精度。不要先对展示数量四舍五入再冒称源码结果。本文未编译或部署合约,未查询实际资产,也不从计划中的数量变化推断未来市场价格。