Appearance
揭秘 Puppet V2:一场关于流动性与价格操纵的 DeFi 攻防战
想象一下,你是一个 DeFi 协议的开发者,上一版漏洞百出的 Puppet Pool 刚发布不久,就被聪明绝顶的黑客们攻陷。痛定思痛,你决定卷土重来,引入了更“现代”的工具——Uniswap V2 作为价格预言机,并辅以推荐的实用库。你自信满满,以为这次总能高枕无忧。然而,事实证明,在 DeFi 的世界里,每一次的升级都可能伴随着新的风险,而黑客的智慧,更是永无止境。
这就是 Puppet V2 挑战的核心故事。
挑战概览:目标与你的起点
你的任务是拯救这个 Puppet V2 协议中价值百万 DVT 代币的资金池,并将它们全部安全地转移到指定的恢复账户。
你将从一个令人羡慕的起点开始:
- 20 ETH 的个人资产
- 10000 DVT 代币 的手中余额
- 而最关键的是,Puppet V2 协议的资金池中,锁定了高达 1,000,000 DVT 代币!
深入剖析:Puppet V2 的工作机制
Puppet V2 的核心逻辑在于一个名为 PuppetV2Pool 的智能合约。它允许用户借用 DVT 代币,但前提是需要存入三倍于借款金额的 WETH 作为抵押。
关键点在于,这个协议如何衡量“三倍”?它依赖于一个Uniswap V2 交易对来作为价格的“预言机”。PuppetV2Pool 使用 UniswapV2Library 来查询这个交易对的储备量,并据此计算用户需要存入多少 WETH 才能借到特定数量的 DVT。
这里的核心漏洞点就在于: Uniswap V2 的价格预言机,虽然比直接依赖外部预言机更加透明,但它本身是可以被操纵的。通过向 Uniswap V2 池中注入或移除大量的某一资产,可以显著地改变该交易对的相对价格。
你的武器库:代码的智慧
挑战提供了一个测试环境 (PuppetV2.t.sol),其中包含了搭建场景所需的一切:
- DVT 代币 (DamnValuableToken) 和 WETH
- Uniswap V2 Factory 和 Router,用于创建和管理交易对
- PuppetV2Pool 智能合约本身
- 还有你将要编写的攻击合约 (MyContract)
你的任务就是利用 MyContract 来执行一次精心策划的攻击。
攻击思路:价格操纵与资金套利
成功的关键在于利用 Uniswap V2 的价格波动来“欺骗” PuppetV2Pool。整个流程可以大致分为以下几步:
准备阶段:
- 你的攻击合约需要一些初始的 WETH,可以从你拥有的 ETH 转换而来。
- 你需要将你手中的 DVT 代币转换为 WETH。为什么?因为我们需要用 WETH 来“影响” Uniswap V2 的价格。
价格操纵:
- 利用 Uniswap V2 Router,将你从手中 DVT 兑换成 WETH。这个过程中,会有一部分 DVT 进入 Uniswap V2 的流动性池,从而降低 DVT 的价格(相对于 WETH)。
- 现在,DVT 在 Uniswap V2 中的价格变得比
PuppetV2Pool认为的要低。
套取资金:
- 因为 DVT 的价格被操纵得更低了,
PuppetV2Pool会认为它需要更少的 WETH 来抵押以借出 DVT。 - 你的攻击合约现在可以调用
PuppetV2Pool的borrow函数,以极低的 WETH 成本,借出池中几乎所有的 DVT 代币。
- 因为 DVT 的价格被操纵得更低了,
资金回笼与转移:
- 将借出的 DVT 代币转移到指定的 recovery 地址。
- (可选但推荐)如果你的攻击合约还剩余 WETH,可以将其兑换回 DVT,然后再转移到 recovery 地址,以最大化收益。
解决方案精要 (代码部分提示)
提供的 MyContract 解决方案展示了上述攻击思路的实现:
constructor函数:接收了攻击所需的所有必要参数,包括玩家地址、代币合约、Uniswap Router、PuppetV2Pool 合约、恢复地址以及你手中的 DVT 数量和截止时间。weth.deposit{value: playerETH}();:将玩家的 ETH 存入 WETH 合约,获得 WETH。token.transferFrom(player, address(this), dvtValue);:将玩家手中的 DVT 代币转移到你的攻击合约。router.swapExactTokensForTokens(...):这是价格操纵的关键步骤。用你的 DVT 在 Uniswap V2 中换取 WETH,从而压低 DVT 的价格。pool.borrow(amountToBorrow);:利用被操纵的低价格,从PuppetV2Pool中借出池中几乎所有的 DVT。token.transfer(recovery, amountToBorrow);:将借出的 DVT 全部转移到 recovery 地址,完成任务。
总结
Puppet V2 挑战是一个经典的 DeFi 价格操纵攻击案例。它巧妙地结合了 Uniswap V2 的预言机机制和智能合约的抵押借贷功能,提醒我们:
- 价格预言机的可靠性至关重要:任何依赖于外部价格信息(包括去中心化交易所的池内价格)的协议,都必须考虑价格被操纵的可能性。
- 流动性是双刃剑:充足的流动性保证了交易的顺畅,但过少的流动性也更容易被操纵。
- 开发者需具备前瞻性思维:在设计 DeFi 协议时,不仅要考虑预期的使用场景,更要预见潜在的攻击向量,并设计相应的防御措施。
成功解决 Puppet V2,你不仅完成了挑战,更深入理解了 DeFi 世界中那些“看不见”的风险与机遇。