作者:Yudan@慢雾安全团队
前言
据《连锁新闻》报道,DeFi项目的yfvalue(YFV)昨天宣布,团队在YFV质押池中发现了一个漏洞,恶意参与者利用该漏洞分别重置了质押中的YFV计时器。已经有恶意参与者试图勒索团队。慢雾安全小组对此进行了深入分析,以下是相关技术细节。
详细分析
以上是yfvalue的官方描述https://medium.com//yfv.finance/yfv-从声明中,我们可以知道YFV抵押贷款池存在问题。恶意用户可以重置YFV抵押人的定时器,给YFV抵押人带来不便,但不会造成资金损失。
通过yfvalue(https://yfv.finance/locking)可以发现,在yfvalue系统中,用户可以通过质押相关代币获得相应的奖励。目前,yfvalue支持以下质押代币池:
可以看出,由于漏洞,YFV抵押池的抵押功能在UI界面中已经关闭,但在合同中token抵押功能没有关闭。我们需要跟踪代码来分析具体细节。
根据官方网站上提供的GitHub地址,我们追踪到了相关代码库(https://github.com/yfv-finance/audit)YFV按揭的相关逻辑在YFVu中标桩.SOL在合同中,合同中有两种抵押功能,即取得功能和保管自**。具体代码如下:
函数股份(uint256金额,地址引用)公开更新(消息发送者)checkNextEpoch{require(amount;0,“Cannot stake 0”);require(推荐人!= 消息发送者,“您不能推荐自己。”);超级代币股份(金额);**停留时间[消息发送者= = 块.时间戳排放标记(消息发送者,金额);如果(rewardReferral!=地址(0)和推荐人!=地址(0)){IYFv转介(rewardReferral)。setReferrer(消息发送者,推荐人);}
职能部门代表(地址监视,uint256金额)公开更新(监视)checkNextEpoch{要求(金额>0,“不能持股0”);超级代币保管(监视,金额);上次监视时间[监视时间]=块.时间戳;以及;emit Staked(stakeFor,amount);}
通过代码不难发现,无论是栈函数还是stakeonself函数,逻辑基本相同。首先,验证morage amount不能为0,然后分别调用上层的tokenstage和tokenstakeonhalf函数。然后更新用户的抵押时间。只是stakeonself函数可以用来抵押别人。tokenstack和tokenstakeonself的代码如下:
函数tokenStake(uint256 amount)内部{totalSupp=总供给量.add(金额)余额[消息发送者]=余额[消息发送者].增加(金额);安全转移自( 消息发送者,地址(此),金额);}
函数tokenstakeonrepresentation(address stakeFor,uint256 amount)内部{totalSupp=总供给量.add(amount);balances[stakeFor]=balances[stakeFor].add(金额);安全转移自( 消息发送者,地址(此),金额);}
如您所见,这里我们简单地以transferfrom的方式将相应的token转移到契约中。没有特别的逻辑点。在这里,整个抵押过程非常清晰,其次是收益过程。分账功能用于计算用户收入,提取功能用于收取收入。代码如下:
函数stakeReward()public updateReward(消息发送者)checkNextEpoch{uint256 reward=getReward();需要(奖励>0,“赚得太少”);超级代币股份(奖励);**时刻[消息发送者] = 块.时间戳;发射标记(消息发送者,奖励);}函数取款(uint256金额)public updateReward(消息发送者)检查nextepoch{require(amount;0,“无法提取0”);require(块.时间戳gt;=解冻所需时间(消息发送者),“硬币仍然冻结”);超级代币提取(金额);排放提取(消息发送者,金额);}
通过对税收征管代码的分析,发现其逻辑也非常简单。stack函数首先通过updaterward修饰符更新用户的奖励,然后使用getreward函数计算用户的奖励,并将抵押时间设置为当前阻止时间。**,当用户提取奖励时,取款功能会先计算当前的区块时间,然后与解冻taketime函数中计算的时间进行比较。只有当当前冻结时间大于解冻取款计算的时间时,才允许取现。解冻taketime的代码如下:
函数unfrozenStakeTime(address account)public view returns(uint256){return lastStateTimes[account]+FROZENuulogenuuTime;}
从代码中,unfrozen taketime是用户**一次抵押时间加上冻结锁定时间,时间常数得到锁定时间。只要超过时间,就可以通过提取功能提取利润。整个抵押和收益的简化过程如下:
经过大量分析,回到我们最初的问题,恶意用户如何锁定其他用户的资产?
回到用户抵押的逻辑,我们可以发现抵押逻辑中stakeonself函数的目的是帮助抵押。然而,这里有一个问题。如果用户之前有抵押呢?如果已经被抵押的用户再次被抵押,例如,如果一个YFV被抵押,那么抵押用户的定时器是否可以以非常低的成本重置,这样用户在取款时就无法成功调用它。此外,假设YFV抵押用户成功调用了stacereward函数,恶意用户在即将达到解冻taketime函数指定的时间时,可以使用stakeonbehave函数将少量资产抵押给用户,然后再次锁定抵押奖励。理论上讲,这种循环会使使用者无法取出自己的资产,但这个问题不会导致资金损失。攻击过程如下:
从前面翻倒的大车上发出警告
这是本月第二次非审计项目曝光,根据YFWalue(YVALUE.O:行情)的官方声明https://medium.com//yfv.finance/yfv-项目代码由经验丰富的开发人员开发,同时借鉴其他成功项目的代码,但仍存在不可避免的风险。科技产业有其特殊性。安全审计一方面需要项目方的积极思考,另一方面需要专业安全团队的逆向思维,从专业黑客的角度模拟对抗,发现问题。
修复计划
通过对代码和漏洞细节的分析,修复方案也非常简单。抵押时只要检查用户的抵押状态,如果已经抵押,则不允许再抵押。或者单独处理每笔房贷不能影响之前的按揭状况。
文章标题:一行代码怎么能锁定数亿资产?
文章链接:https://www.btchangqing.cn/92384.html
更新时间:2020年08月26日
本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。