banner
zach

zach

github
twitter
medium

ダム・ヴァルナラブル・ディファイ | 止められない

チャレンジ #1 - 止まらない#

止まらない

コントラクト#

  • ReceiverUnstoppable:IERC3156FlashBorrower コントラクトを継承し、フラッシュローンを実行した後のコールバックを行うためのものです。
  • UnstoppableVault:IERC3156FlashLender、ERC4626 を継承した金庫コントラクトで、フラッシュローンをサポートしています。

スクリプト#

  • DamnValuableToken、UnstoppableVault コントラクトを順番にデプロイします。
  • TOKENS_IN_VAULT の数だけトークンを金庫に預け入れ、INITIAL_PLAYER_TOKEN_BALANCE の数だけトークンをプレイヤーのアカウントに転送します。
  • ReceiverUnstoppable コントラクトをデプロイします。
  • 攻撃スクリプトを実行します。
  • ReceiverUnstoppable が実行されたフラッシュローンのトランザクションが revert されることを期待します。

解答#

攻撃の目標は、ReceiverUnstoppable コントラクトから実行される executeFlashLoan メソッドが revert されることです。まず、executeFlashLoan の呼び出しフローを分析します。

image

重要なのは、UnstoppableVault.flashLoan メソッドで、以下の操作が行われます。

  • フラッシュローン開始前の残高を計算する:totalAssets ()
  • 現在のシェアを計算する:convertToShares (totalSupply) が先に計算した残高と一致するかどうか
  • フラッシュローン手数料を計算する:flashFee
  • amount 個のトークンを receiver に転送し、receiver の onFlashLoan メソッドを呼び出してコールバックを実行する
  • amount+fee の数だけトークンを receiver から返す
  • fee を feeRecipient アカウントに転送して、フラッシュローンを完了する

トランザクションを revert させるためには、convertToShares(totalSupply) != totalAssets()となるようにする必要があります。

これらの関数は、ERC4626 で定義されています。このプロトコルについては、以下の記事を参照してください:
WTF-Solidity/51_ERC4626/readme.md at main · WTFAcademy/WTF-Solidity

簡単に言えば、ERC20 の組み合わせで、アセットトークンとシェアトークンがあります。アセットを預け入れたり引き出したりすると、対応する数のシェアトークンが鋳造または破棄されます。

  • totalAssets():現在の金庫のアセットトークンの数を計算します。
  • convertToShares(totalSupply):totalSupply は総シェアトークンの数です(デポジットまたはミント時にのみ生成されます)。convertToShares は、assets * totalSupply /totalAssets () を計算するものです。

これらの関数を一致しないようにするには、UnstoppableVault にトークンをデポジットまたはミントする必要がありません。したがって、攻撃スクリプトの内容は以下の通りです:

it('Execution', async function () {
        /** CODE YOUR SOLUTION HERE */
        const dvtForPlayer  = token.connect(player);
        await dvtForPlayer.transfer(vault.address,1);
    });
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。