C.R.E.A.M. Finance Post Mortem: AMP事件の事後レポート

C.R.E.A.M. Financeコミュニティ、パートナー、いつもご利用いただいている皆様、まず初めに私たちは本事件は既に阻止したことをご報告します。

今回の事件に伴いまして、ご心配をおかけした皆様、大変に申し訳ございませんでした。ご協力いただいた皆様に感謝申し上げます。

C.R.E.A.M. Financeはコミュニティ、パートナー、ユーザー、トラストレス、自動化、資本効率の向上に献身しています。私たちは私たちのユーザーとコミュニティを最優先で考えています。現在、私たちは当局と協力のうえで攻撃者を追跡し、失われた資金を取り戻す計画を立てています。いかに、本事件に関する報告を記します。

事件内容

2021年8月31日 13:00(日本時間)ごろ、何者かがC.R.E.A.M. Financeから462,079,976 AMP、2,804.96 ETHを不正に入手しました。この事件に加えて、少額を不正に引き出した模倣犯もいましたが、模倣犯のアドレスを辿ったところBinanceからの出金履歴があり、Binanceとの協力のうえで身元の特定に成功しました。私たちは模倣犯を起訴することを予定しています。

本事件の最初のトランザクションはこちら

模倣犯の最初のトランザクションはこちら

なぜ事件はおきたか

AMPのトークンコントラクトはERC-777を実装しており、受信者が実装したtokensReceived()関数をトリガーする_callPostTransferHooksというコードを持っています。ERC-777形式の転送フックに関連するリエントランシー機能を利用して、犯人は最初のborrrow()がアップデートされる前に、トークン転送()の中に2つ目のborrow()関数を組み込みました。これが17のトランザクションで繰り返されました。

私たちは、Flexaチームと緊密に連携して本犯行の詳細を解明し、そのコントラクト自体は正常に機能していたことを突き止めました。本犯行を許した脆弱性はAMPのコードのバグによるものではありません。PeckShieldの強力を得た、私たちのAMPのプロトコルへの統合方法に誤りがあったことが原因であると判断し、本事件に関する全責任を負うことを決定しました。

事件後の対応

AMPの貸し出し・借り入れを一時的に停止しています。パッチを安全に適用できるようになった時点でAMPマーケットを再度有効化する予定です。今後、同様の攻撃からプロトコルを安全に保護するため、監査役やテクニカルアドバイザーと協力していきます。

被害者への対応

今回のようにプロトコルが悪用されると、それを喜ぶ声も多く上がりますが、私たちは業界、パートナー、そして最も大切に考えているユーザーたちのために尽力し続けます。

私たちは盗まれたETHとAMPをプロトコルに補填し、流動性に問題が生じないようにします。さらに本件に関する負債を完済するまで、徴収しているプロトコル手数料の20%を返済に充てていきます。それまでの期間、Flexa/AMPチームとの間にCREAMで担保を設定します。影響を受けたユーザーの方がいらっしゃいましたらこちらのGoogleフォームから詳細をお知らせください。私たちは今回の犯行により被害を受けた方々のために全力を尽くすことを誓います。今後とも革新的なDeFiプロダクトの構築に尽力し、パートナーやコミュニティの皆様のご支援に感謝しつつ共に前進したいと考えております。

資金のリカバリーに関する報奨金

本事件の犯人が自ら盗んだ資金を返金する場合には、通常のバグ報酬金の10%を付与いたします。

他の方が犯人の逮捕と起訴に繋がる情報を提供してくださった場合には返還される資金の50%を情報提供者に分配します。

私たちは関係当局と連携し、あらゆる手段を講じます。

C.R.E.A.M. Financeは革新を続けます

私たちには長期的な目標があります。その目標の達成のため、C.R.E.A.M. Financeは今後も革新と開発を続けていきます。今回の失敗を教訓とし、C.R.E.A.M.プロトコルをさらに強化する機会にしたいと考えています。私たちは、分散型レンディングマーケットに高い資本効率をもたらし、個人、機関、プロトコルの金融ニーズを満たすという使命を今後も持ち続けます。今後ともよろしくお願いします。

C.R.E.A.M. Finance

事件の詳細

本事件の脆弱性は2021年2月10日にC.R.E.A.M. FinanceにAMPを担保資産の1つとして上場したことに始まります。crAMPが公開されてからも本事件発生までの間、AMPの供給量が少なかったため悪用されていませんでしたが、5日前にcrAMPマーケットに大量にAMPが供給されたことにより、犯行が可能となりました。このベクトルを実行するとプロトコルが攻撃用コントラクトのアドレスに対して不良債権を抱えることになるため、各攻撃用コントラクトは1度のみしか利用できませんでした。犯人は、10回の改訂を実行するまでに間に重複した攻撃用コントラクトを配備して7回の攻撃を繰り返しました。

# nested borrow https://etherscan.io/tx/0xba468e260588e659d308413bf14c5b466fb13ee6423a96587ad1eee4a81bb802 https://etherscan.io/tx/0x8b4ec34be08527e549b7fc4863f23ca8a9c65824ac62a4327bd803f8cbb83fc2 https://etherscan.io/tx/0xf5a3225fd62ed183af9df48dd9b725727f8975d251165b40972cf54b3198fd70 https://etherscan.io/tx/0x51fd83401f2be2e16fed9c02c7f7df683e1f0c4bcc7cdccf58a1d810824c4992 https://etherscan.io/tx/0x55692ccc8ccf81b155044ed4109155ec7714dfae541fe4c4be23da8b18240248 https://etherscan.io/tx/0x77e2d72bd9d94f20b051f0a629a79e9a316b3ee3c6bf7495236f43bc24d379d8 https://etherscan.io/tx/0x0016745693d68d734faa408b94cdf2d6c95f511b50f47b03909dc599c1dd9ff6# nested borrow, then liquidate and seize https://etherscan.io/tx/0xa9a1b8ea288eb9ad315088f17f7c7386b9989c95b4d13c81b69d5ddad7ffe61e https://etherscan.io/tx/0x1d20ea6596943a38376bef5d3b68d67db275061257c7af5a05334212563c2028 https://etherscan.io/tx/0x1c3464135a0d7b0e770d53afe57b9ff0de70803bbf2e8f7714ea71022447f288 https://etherscan.io/tx/0x6afb3e8e318e221711715c3e2017661ad35ef92e083f7554372ce8ffcaf7da6d https://etherscan.io/tx/0x5452e5ff92a628bbebe732441e2b10cf428d7e0170004665c6b689180642533f https://etherscan.io/tx/0xf0f6a07e0d27b00b972ccdfa500cb53f87ff3e079a3746afb3af6ca84a186043 https://etherscan.io/tx/0x6f3bc128724bdae00f328e300d74103d0adcf988720b0b02f65b6f258af276fa https://etherscan.io/tx/0x487364b6de9e00015c571017c00fd5078c795822a4387af4d95962e50112bc06 https://etherscan.io/tx/0xd7ec3046ec75efbd04b3eea8752a8a6373a92c0dd813d08b655661054d3239c5 https://etherscan.io/tx/0xc90468d698700757f33543039c7cb10d4ca49d57b5417789e7656e73019de674

攻撃の第一波では、攻撃者はまずcrETHマーケットでETHを担保として供給し、次にcrAMPマーケットからAMPの融資を受けました。AMPを攻撃コントラクトに転送する間に_callPostTransferHooksが呼び出され、これにより外部のコントラクトコールが実行されることで、crETHにリエントランスし、全く同じETHを担保にAMPを借り入れました。

具体的にはこの脆弱性はAMPトークンのERC-777実装と組み合わせてtokenReceivedフックを呼び出した際に私たちの借入関数内で発生していました。

crTokenコントラクトではストレージのアップデート前にローンを転送しています

AMPはERC-777トークンのようなものなので、tokenReceivedフックが呼び出されています

これにより、犯人は最初のborrow()が実行を完了する目に、2つ目のborrow()関数をネストさせることができ、その結果通常許可されている以上の融資を受けることが可能となってしまいました。

第一波の攻撃

第一波の攻撃を説明するためにこちらのトランザクションで説明します。

  1. 攻撃コントラクトAは100ETHを預けて4,834.46565933 crETHを取得しました。
  2. 攻撃コントラクトAは3,896,000 AMPを借り入れ、さらに71 ETHを借りました(現在はこの時点で攻撃コントラクトは担保不足で精算可能)。

結果的にこの攻撃トランザクションによりC.R.E.A.M. Financeは38,960,000 AMPを失い、100–71=29 ETHを得ています。攻撃コントラクトは担保不足となり、flashbotsはその後の清算で8%を返済して差し押さえました。

第二波の攻撃

第二波では犯人はコントラクトを修正し、自身の担保不足になっている債務を生産しました。こちらのトランザクションで説明します。

  1. 攻撃コントラクトAは2,000ETHを預けて96,689.19905008 crETHを取得しました。
  2. 攻撃コントラクトAは77,920,000 AMPを借り入れ、さらに1,420 ETHを借りました(現在はこの時点で攻撃コントラクトは担保不足で精算可能)。
  3. 攻撃コントラクトAが攻撃コントラクトBに38,960,000 AMPを送信
  4. 攻撃コントラクトBは、38,960,000 AMPをcrAMPマーケットに返済することで攻撃コントラクトAを清算し、攻撃コントラクトAの担保から35,529.572 crETHを差し押さえました。
  5. 攻撃コントラクトBは35,529.572 crETHを利用して734.923 ETHを引きだしました。

結果的にこれらのトランザクションにより、C.R.E.A.M. Financeは2,000–1,420–734,923=154.923 ETH と 77,920–38,960,000=38,960,000 AMPを失いました。

結果と改善

総損失資産: 462,079,976 AMP + 2,804.96 ETH

  1. 本事件の発覚後、直ちにC.R.E.A.M. FinanceとIron Bankのすべてのマーケットを調査し、ERC-777に似たトークンが無いことを確認しました
  2. 本事件を受けて、私たちは以下の方法でプロトコルのセキュリティを強化します。
  • C.R.E.A.M. Financeのプラットフォームへの新規トークン上場に関する標準作業手順を強化し、トークンコントラクトの実装を厳重にチェックします。これには、プロトコル上のコアアクションを実行するテストトランザクションでのCALL opcodeの調査や、バニラではないすべてのTransfer/TransferFrom機能の実装による潜在的な影響の調査を含みます。
  • 既存のリエントランシーガードはコントラクトレベルでのリエントランシーを防ぐのみなので、プロトコル内でのリエントランシーを防ぐプロトコルレベルのノンリエントランシーガードを実装します。

--

--