时间:2023-08-22|浏览:160
因此,借贷可以说是富人的游戏。通过借贷手段来合理分配资产,从而获得收益,这也是理财的核心。
大家都会好奇,银行拿我们存的钱去做什么呢?
从某种意义上来说,银行是最大的借债方。如果银行的系统被攻破,强制要求银行“还款”,那么储蓄者账户中本来应该还给他们的钱就会被攻击者拿走,储蓄者和银行都将成为最大的受害者。
北京时间9月21日,CertiK安全研究团队发现soda区块链项目中存在智能合约安全漏洞。通过该漏洞,任意外部调用者可以通过调用智能合约函数,无视受害用户债务中的代币数量,强行清算用户的债务,并将清算所得的收益转入自己的收款地址。
soda项目官方已经提交修复补丁来修复这个安全漏洞。但由于soda项目使用了TimeLock来延迟所有操作48小时,修复补丁将在延迟时间之后生效。截止发稿时,该漏洞已被修复。
漏洞技术分析:
soda项目中的WETHCalculator.sol智能合约存在逻辑实现错误,导致安全漏洞。在第193行,计算公式错误地使用了amount196行的require判断条件loanTotal>=maximumLoan可以转换为:
loanInfo[_loanId].amount+interest>=loanInfo[_loanId].amount*maximumLTV/LTV_BASE
由于maximumLTV/LTV_BASE的值在0.15-0.95之间变动,且interest>=0,所以196行的require判断条件总是为真。
失去了该require判断的保护,任意外部调用者都可以通过调用SodaBank.sol中的collectDebt函数来清空任意贷款ID的贷款。在执行该函数过程中,图一中的collectDebt函数会在图二中被执行,并通过代码将用户在soda中的一部分WETH转移到调用者的地址。
官方修复细节:
soda官方为修复该漏洞,设计了新的智能合约WETHCalculatorFixed.sol来替换WETHCalculator.sol。
通过分析可以看到,在WETHCalculatorFixed.sol的第979行,计算公式被正确地计算为loanInfo[_loanId].lockedAmount*maximumLTV/LTV_BASE。因此,第982行的require判断的检测条件变成了:
loanInfo[_loanId].amount+interest>=loanInfo[_loanId].lockedAmount*maximumLTV/LTV_BASE
该公式与soda项目的逻辑设计相符合,该公式的真假与用户的借贷债务数目和被锁定的本金数目有关。漏洞已经被修复。
关于该等式的逻辑设计细节可以在链接(https://medium.com/soda-finance/the-soda-revolution-9185fdb99fc1)中了解。
事件分析总结:
该漏洞是由于逻辑设计与代码实现不符而导致的。目前常用的单元测试和自动化测试工具无法有效检测到与逻辑相关的漏洞。
因此,CertiK安全团队提出以下安全建议:
1. 安全是区块链项目的基础,上线前应请专业第三方安全审计团队对项目代码进行安全审计。 2. 当前区块链检测工具无法检测到逻辑上的漏洞,并且其结果缺乏可信的数学证明。采用基于形式化验证方法的区块链检测工具来验证项目中的安全漏洞,应成为每个项目上链前的必要步骤。
参考链接: - 图一:https://github.com/soda-finance/soda-contracts/blob/master/contracts/calculators/WETHCalculator.sol#L189 - 图二:https://github.com/soda-finance/soda-contracts/blob/master/contracts/components/SodaBank.sol#L104 - 图三:https://github.com/soda-finance/soda-contracts/blob/master/contracts/calculators/WETHCalculatorFixed.sol#L275