KingDefi收益计算漏洞解析:DeFi协议逻辑缺陷与修复
知道创宇区块链安全实验室在对KingDefi协议进行授权安全审计的时候, 发现其核心收益计算模块存在一处业务逻辑漏洞。该漏洞位于收益结算函数。

攻击者可以通过构造特定的时间戳参数。系统计算的持有天数因此远超实际值。这就使得攻击者获取超出正常范围的DeFi收益。此漏洞不涉及合约字节码缺陷。但它可以造成用户资产损失。
一、漏洞原理
KingDefi采用的是这样一种收益模型, 也就是本金乘以年化利率再乘以持有天数。它的结算函数calcYield()在计算持有天数的时候, 直接拿当前区块的时间戳去减去用户存入时的时间戳, 从而得出天数的差值。
它没有设置一个合理的上限, 也没有去校验时间戳是否是因为区块发生了回滚或者矿工进行了操纵, 从而出现了异常跳变的情况。只要是在正常的网络情况里, 这个逻辑就没有什么不对的地方。可是, 一旦时间戳的差值被人强行加大了的话, 那收益就会按照加大之后的天数来进行结算。
这样的话, 单个账户最高能够拿到的收益, 就是正常时候收益的五倍那么多。
二、影响评估
受影响合约:YieldCalculator.sol,函数calcYield()及settleYield()
当时间戳的差值超过了设定的阈值, 并且这个情况没有被业务层给拦截住的时候, 就构成了触发条件, 在这一过程当中, 不需要去拥有管理员的那些权限。
在资产风险这个方面, 对于单一账户的收益情况来看, 其有可能被放大的程度能够达到正常值的五倍以上。
影响版本:KingDefi v1.0至v2.3
可复现性这一方面的内容就是, 任何一个已经被存入到资产列表里面的那个账户对象, 都是可以依靠自身来独立引发对应的触发行为的。
三、修复方案
1. 在calcYield()函数的入口位置增加时间戳的合理性校验, 把持有天数的上限值设置为365天, 一旦超过这个上限就返回错误码。
2. 计算基准被改变了, 它不再使用时间戳, 而是换成了区块高度, 这个操作是用协议来设定的平均出块间隔去换算成天数的, 这样做是为了降低时间戳存在单点篡改的风险问题。
3. 设置单账户在单个结算周期内的收益上限, 对于超出这一标准的部分会自动实施冻结措施, 并且通知用户进行确认。
4. 对于settleYield()来说, 需要新增异常检测逻辑。如果结算金额超过了近期30日均值的3倍的情况出现时, 应当自动把结算动作给暂停掉。同时还要去触发那个往链上面发的告警操作, 并且也要发送通知给管理员那边去做处理。
四、针对同类的协议, 我们要给出一些防护方面的建议。
在那些和资金计算有关的地方, 像是收益、利息、分润这些模块里面, 得把下面说的这些措施当成是安全的底线来抓起来。对于所有和时间扯上关系的计算步骤来说, 一定要设好上限和下限, 不能让它随便乱算。在选算账的老本的时候, 更提倡用区块高度来当作基础数据, 不要光依赖时间戳这种玩意儿。
碰到那种极端的输入内容, 好比说是负数, 零, 特别大的数值, 还有时间戳突然大变样, 这些情况都得去做一遍完整的边界测试, 确保没问题。等到快上线的时候, 安全团队必须动手去检查逻辑是不是对的, 还得搞一下模糊测试这一套, 反正至少得覆盖住三种那种不正常的时间戳场景才行, 这样才算完事。
这份分析是建立在知道创宇区块链安全实验室拿到了正式授权来进行审计工作这个基础之上的, 关于具体的修复方案到底该怎么弄, 还是应该以KingDefi协议方面最终做出的技术决策为准。
常见问题
《KingDefi收益计算漏洞解析:DeFi协议逻辑缺陷与修复》主要讲什么?
知道创宇区块链安全实验室在对KingDefi协议进行授权安全审计的时候, 发现其核心收益计算模块存在一处业务逻辑漏洞。该漏洞位于收益结算函数。 攻击者可以通过构造特定的时间戳参数。
文章提到了哪些重点?
在calcYield()函数的入口位置增加时间戳的合理性校验, 把持有天数的上限值设置为365天, 一旦超过这个上限就返回错误码;