本文分析了 Damn Vulnerable DeFi V4 的 Unstoppable 挑战,该挑战通过操纵会计系统实现拒绝服务攻击。
此解释假定你事先了解此挑战中的智能合约,并将专门侧重于漏洞分析。
有一个代币化的金库,其中存入了 100 万个 DVT 代币。它免费提供闪电贷,直到宽限期结束。为了在 100% 无许可之前发现任何错误,开发人员决定在测试网上运行一个实时 beta 版。有一个监控合约来检查闪电贷功能的活跃度。从余额中的 10 个 DVT 代币开始,证明可以暂停金库。它必须停止提供闪电贷。
UnstoppableVault 挑战通过会计系统操纵呈现了拒绝服务 (DoS) 漏洞。该金库实现了符合 ERC4626 标准的代币化金库,提供闪电贷,但它包含一个严格的不变量检查,可以利用该检查来阻止所有闪电贷操作。
核心漏洞在于闪电贷功能的 ERC4626 合规性检查:
function flashLoan(...) external returns (bool) {
if (amount == 0) revert InvalidAmount(0);
if (address(asset) != _token) revert UnsupportedCurrency();
uint256 balanceBefore = totalAssets();
if (convertToShares(totalSupply) != balanceBefore) revert InvalidBalance();
// ... rest of flash loan logic
}
此实现存在漏洞,因为它强制执行了一个严格的会计不变量,该不变量很容易被破坏:金库的代币余额必须与份额会计系统期望的完全匹配。由于合约可以通过转账直接接收代币,因此可以在不通过适当的存款机制的情况下破坏此不变量。
convertToShares(totalSupply) != balanceBefore
) 现在永久失败,并显示 InvalidBalance() 错误,从而有效地禁用了金库/**
* 在此处编写你的解决方案
*/
function test_unstoppable() public checkSolvedByPlayer {
token.transfer(address(vault), 1);
}
更好的方法是将存入的资产保存在单独的变量中。asset.balanceOf(address(this)) 不应作为不变量使用。你可以在此处了解有关它创建的漏洞的更多信息:https://blog.sigmaprime.io/solidity-security.html#ether
包含解决方案的 GitHub 存储库:https://github.com/HamMnatsakanyan/damn-vulnerable-defi-solutions/
查看我的 X 个人资料:https://x.com/_synthrax
- 原文链接: coinsbench.com/damn-vuln...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!