2022年4月23日消息,NFT项目方Akutar的AkuAuction合约由于智能合约本身存在的漏洞,导致11539ETH(价值约3400万美元)被永久锁死在合约中,项目方也无法将其从合约中提取出来。
SharkTeam第一时间对此事件进行了技术分析和资金流向分析,并总结了安全防范手段,希望后续的区块链项目可以引以为戒,共筑区块链行业的安全防线。
一、漏洞分析
漏洞合约地址:0xF42c318dbfBaab0EEE040279C6a2588Fa01a961d
首先,我们需要了解一下AkuAuction合约中提款的逻辑,项目方的提款函数如下:
这里,存在3个校验,如下:
第一个是时间校验,即提款必须在所有的拍卖进程完成后进行。
第二个是退款校验,即提款只能在所有用户都完成退款后才可以提款。
第三个是空投校验,即空投全部完成后才可以提款。
这3个校验的目的是在合约层面限制项目方的提款权限,保证用户的权益,提高项目的可信程度。这3个校验带来的应该是安全可信的,为什么会出现代币锁死而无法提取的情况呢?原因就在于第2个校验在实现时存在错误,无法达到预期的目标,如下:
这里,refundProgress指处理的退款数量,即退款账户的数量,退款处理函数processRefunds代码如下:
从该函数中,我们可以看到,refundProgress的比较对象应该是bidIndex,这里的bidIndex指的是投标账户的总数,在bid函数中,每当有一个账户投标,bitIndex就会加1,且不会重复,代码如下:
在claimProjectFunds函数中,退款校验比较的却是refundProgress >= totalBids,这里的totalBids不是投标账户的总数,而是所有用户总投标的NFT总数,如果1个账户只能投标1个NFT,该比较在数量上不会有问题。实际上在bid函数中,1个用户可以投标多个NFT,代码如下:
因此,实际的totalBids>= bitIndex。当有用户投标2个及以上的NFT时,totalBids> bitIndex。当所有用户都完成退款时,refundProgress == bitIndex 另外,在退款处理函数processRefunds中,还存在另外一个漏洞,代码如下: 在循环调用的过程中,使用call函数进行退款,并检验其结果,若结果为false,则回滚。该逻辑容易引起拒绝服务攻击,即只要循环中有一次退款不成功,那么退款处理函数就会一直回滚,拒绝服务。 二、安全建议 针对本次事件中的安全漏洞,我们提出以下建议: (1)对于开发者,要思维逻辑严谨,并且要具备基本的安全性意识,在项目开发过程中, 保证代码逻辑缜密并与实际逻辑相符,尽量避免一下基本的逻辑和语言层面的安全问题。 (2)项目在测试过程中,要尽可能的全面,尤其是业务逻辑方面。 (3)推荐项目方选择审计单位对项目进行审计后再上线,进一步提高项目的安全性,规避一些安全风险。 通付盾链上安全团队(SharkTeam)是领先的区块链安全服务团队,精通区块链和智能合约底层原理,为开发者提供合约审计和应急响应服务,合约审计包含近200项审计内容,覆盖高级语言层、虚拟机层、区块链层和业务逻辑层,全面保障智能合约安全。 Website: https://www.sharkteam.org/ Telegram: https://t.me/sharkteamorg Twitter:https://twitter.com/sharkteamorg 更多区块链安全咨询与分析,点击下方链接查看 D查查|链上风险核查https://m.chainaegis.com