Day12 実行ログ(2026-07-22 更新)

実装

  • 脆弱/安全コントラクト:contracts/VulnBank.sol, SafeBank.sol, Attacker.sol を追加。VulnBankはCEI違反(bal更新が送金後)で再入攻撃可能、SafeBankは ReentrancyGuard + CEI 順守。
  • 権限管理例:contracts/AdminBox.sol(Ownable + Pausable)。
  • テスト:test/reentrancy.ts を実装し、VulnBankが攻撃で枯渇する一方、SafeBankは攻撃Txがrevertすることを確認。
  • Foundry invariant:test/Invariant.t.solで、3 actorの内部台帳合計・contract assets・ghost net depositsの一致をstatefulに検査。test-negative/UnsafeAccountingInvariant.t.solの1 wei mutationが同じpropertyを破ることも自動確認。

コマンド

# 依存を復元(OZ v5)
npm run install:reviewed

# 再入テストのみ
npx hardhat test test/reentrancy.ts
# 全体テスト
npm test

# Foundry v1.7.1: executable invariant + expected-failure mutation
npm run test:foundry

結果:test/reentrancy.ts2 passing。Hardhat全体は既存Mocha 16件とSolidity invariant 1件の計17件が成功した。Foundryの通常invariantは128 runs / 4,096 calls / revert 0で成功し、negative mutationは期待どおり非0終了して検出された。

観測

  • VulnBank へ10 ETH預けた状態で Attacker.attack() を実行すると、bal[msg.sender] が未更新の間に再入され、残高が9 ETH未満まで減少。
  • SafeBanknonReentrant + 先に残高更新を行うため、攻撃Txは revert し drain 不発。
  • AdminBox(Ownable+Pausable)は Day04/Day11 のサンプルに適用できる汎用テンプレートとして用意。

静的解析/ファジング

  • Foundry v1.7.1でhandler、target contract、bounded input、ghost accountingを使う実行可能invariantを確認済み。
  • Slither / Echidna は外部ツール導入と追加設定が必要なため実行していません。手順メモ:
    • pipx install slither-analyzer
    • slither . --filter-paths node_modules
    • Echidnaを追加する場合は、Foundryと別ツールであることを維持し、propertyとtargetを個別に定義する。

まとめ

  1. Day12 で扱う再入/権限対策をコードベースに具体化し、攻撃成功/失敗を自動テストで確認できる状態にした。
  2. AdminBox などのアクセスポリシー雛形を追加したことで、教材の他コントラクトにも Pausable/Ownable を適用しやすくなった。
  3. 通常green invariantだけでなく、意図的なaccounting欠陥を検出するnegative fixtureにより、propertyが反証可能であることを固定した。