Vesting-安全
VET-01: Vesting 时间结构是否存在逻辑一致性问题?
描述: Vesting 结构依赖 start、cliff、duration、end 等时间变量计算释放曲线,若这些参数之间缺乏严格的数学约束,可能导致释放逻辑出现结构性错误,例如提前释放、永久锁仓或瞬时全部释放。在支持多阶段释放、参数可修改或批量创建 Vesting 的架构中,时间区间错配更容易发生,并可能影响所有受益人资金安全。此外,若未防止 end 计算溢出或时间倒退,也可能导致释放比例异常。
建议: 在初始化和任何时间参数变更时必须进行完整一致性校验,确保 cliff 不早于 start、duration 大于零、end 严格等于 start 加 duration,并防止溢出。建议将时间计算逻辑集中在单一内部函数中统一处理,避免多处分叉计算造成逻辑不一致。
VET-02: 释放计算是否存在精度损失或尾差锁定风险?
描述: 线性 Vesting 通常采用整数比例计算已归属数量,而 Solidity 的整数除法会向下取整,可能导致最后阶段存在微量余额无法释放的情况。若未在释放结束时进行兜底处理,可能产生永久锁仓的尾差问题。在大规模或长期 Vesting 场景下,该问题会形成系统性资产沉淀。
建议: 在当前时间达到或超过 vesting 结束时间时,应直接释放全部剩余 allocation,而非继续使用比例公式计算。应统一采用先乘后除的比例计算方式,并通过边界测试覆盖极小 allocation 与极长 duration 场景。
VET-03: 是否存在重复领取或超额释放风险?
描述: 若合约在计算可领取金额时未严格使用已归属减去已领取的模式(
vested - claimed),或在多路径释放逻辑中存在状态更新顺序问题,可能导致重复领取或超额释放。该问题在支持追加 allocation、可撤销 Vesting 或多批次 Vesting 的复杂结构中尤为常见,一旦状态不同步,将直接造成资金损失。建议: 所有释放路径必须统一通过内部函数计算
vested - claimed,并在转账前更新已领取状态以避免重入影响。应避免在多个函数中独立计算可领取金额,并增加多次领取与边界时间的测试覆盖。
VET-04: 是否存在 Push 模式导致的拒绝服务风险?
描述: 若合约在发放时主动向受益人转账(Push 模式),当接收方为恶意合约或在 fallback 中消耗大量 Gas 时,可能导致交易整体回滚。在批量发放或循环处理场景中,单一恶意地址即可阻断整个流程,形成拒绝服务风险。
建议: 采用 Pull Claim 模式,由受益人主动调用 claim 领取资产,避免在循环中进行外部调用。若必须使用 Push 模式,应避免批量循环并妥善处理失败逻辑。
VET-05: 可撤销 Vesting 是否正确区分已归属与未归属资产?
描述: 在 Revocable Vesting 结构中,若撤销逻辑未正确计算当前已归属与未归属部分,可能导致管理员错误收回已归属资产,或受益人提前获得未归属资产。此外,若撤销后未冻结后续释放逻辑,可能出现撤销后仍可继续领取的异常状态。
建议: 撤销时必须实时计算当前已归属数量,并仅允许回收未归属部分,同时在撤销后锁定 Vesting 状态以防止继续释放。建议通过独立函数计算 vested 数量,避免在撤销与领取逻辑中出现计算分叉。
VET-06: 是否存在重入风险影响释放状态?
描述: 若在更新已领取状态前进行外部 token 转账调用,攻击者可能通过重入再次调用 claim 函数,从而多次提取资金。尤其在使用 ERC777 或存在可回调代币时,该风险会被放大。
建议: 遵循 Checks-Effects-Interactions(检查-生效-交互)模式,在转账前更新领取状态,并在必要时使用 ReentrancyGuard 防护。同时避免在同一函数内执行多个外部调用。
VET-07: 多受益人批量 Vesting 是否存在 Gas DoS 风险?
描述: 若合约支持批量创建或批量释放 Vesting,并在单次交易中循环处理大量受益人,可能因 Gas 限制导致交易失败。在极端情况下,攻击者可通过构造大量数据使某些函数永久不可执行。
建议: 避免在单一交易中进行不受限制的循环处理,应采用逐个领取或分批处理的架构设计,并限制数组长度或引入分页机制。
VET-08: 是否存在权限集中或治理滥用风险?
描述: 若管理员可以修改 Vesting 参数、追加 allocation、提前解锁或强制撤销,而缺乏时间锁或多签机制,则可能形成中心化风险。受益人资金可能在链上结构正确的情况下被治理层单方面改变。
建议: 关键权限操作应通过多签或 Timelock 控制,禁止任意修改已生效的 Vesting 核心参数,并对关键治理操作进行事件记录与透明化披露。
VET-09: 撤销机制是否存在抢跑(Front-running)提取风险?
描述: 在可撤销的 Vesting 合约中,若管理员发起撤销(Revoke)交易,受益人能在 Mempool 中监控到该交易,并可能通过提高 Gas 费(Front-run)抢先调用
claim函数提取尚未被撤销的代币。这种时间差可能导致管理员撤销意图部分失效。建议: 撤销逻辑应基于固定的时间戳(如管理员指定过去的某个时间点或触发事件区块)进行核算,或者合约设计支持一键暂停(Pause)功能,在暂停后再进行撤销清算,避免执行顺序带来的状态不一致。
VET-10: 是否存在 allocation 可被重复覆盖风险?
描述: 若为同一受益人创建多条 Vesting 记录,但未正确区分批次,可能导致原有的 allocation 被错误覆盖或合并,从而使受益人丢失资产或计算混乱。
建议: 为每条 Vesting 生成唯一 ID 或使用数组记录多批次状态,并单独存储各批次的释放进程,避免直接覆盖原本的状态变量。
VET-11: 是否存在中途追加 allocation 导致释放曲线扭曲?
描述: 若在 Vesting 进行中直接修改已有的 allocation(例如增加总量),但未同步重新计算相应的释放比例与已领取状态,可能导致系统按照新的总量计算旧时间段内的额度,使得部分 token 被不合理地立即释放。
建议: 任何追加 allocation 的操作均应避免修改原始 Vesting 结构,必须作为一笔全新的 Vesting 批次处理,确保旧有曲线平滑执行。
VET-12: 是否存在经济模型设计缺陷?
描述: 若 Vesting 曲线与代币经济模型不匹配,例如大量代币集中在极短的 cliff 结束后同时释放(断崖式释放),可能对二级市场造成剧烈抛压和价格冲击,偏离项目设计的初衷。
建议: 在设计阶段应进行代币释放压力测试与经济模拟,选择更平滑的线性或指数释放模型,以此缓和市场抛压。
VET-13: 是否存在资金不足导致释放失败风险?
描述: 若 Vesting 合约的执行依赖未来充值,或未在创建时提前锁定足额 token,受益人在调用 claim 时可能会因合约自身余额不足而导致交易回滚(假性 Vesting)。
建议: 在创建 Vesting 时强制要求从创始地址转入或提前锁定等于全部 allocation 的代币,或在领取操作时进行清晰的余额校验和异常事件抛出。
VET-14: 受益人地址转移机制是否存在越权或覆盖风险?
描述: 部分 Vesting 合约出于员工离职、私钥丢失等代管需求,允许转移受益人地址。如果转移逻辑未严格清空原地址的权限或状态,可能导致新旧地址双重提取。此外,如果新地址已被用于其它 Vesting,可能出现状态覆盖风险。
建议: 转移地址时必须验证发起方授权,并将原地址的已归属、已领取状态完整迁移至新地址(或使用新 ID 映射),迁移后彻底注销原地址对该批次 Vesting 的所有访问权;同时校验新地址是否已存在重叠状态。
VET-15: 代币本身特性(如通缩机制/非标准 ERC20)引发的计算偏差?
描述: 如果 Vesting 的代币是带有燃烧机制(Fee-on-transfer)或变基机制(Rebase)的非标准 ERC20 代币,合约实际收到的数量可能小于入账数量。在后续 claim 时,按原始 allocation 计算可能导致最后提取的受益人无法足额领取甚至交易失败。
建议: 检查 Vesting 是否支持非标准代币。若必须支持,应使用转账前后余额差值(
balanceAfter - balanceBefore)确立实际 allocation,或在合约中记录份额而非绝对代币数量。
