
北京時間2021年8月4日午前6時(ブロック12955063)、Popsicle Financeプロジェクトの複数のスマートプールが攻撃され、2,000万米ドル以上の損失が発生しました。これは、DeFi分野での単一損失としては群を抜いて最大です。攻撃の一つ。分析後攻撃トランザクションそしてプロジェクトコード この攻撃はプロジェクトの会計の抜け穴を悪用し、複数回の出金(報酬の二重請求)を行う攻撃であることが判明しました。以下では、コードと攻撃プロセスを通じて攻撃を分析します。
コード分析
Popsicle Finance は、複数のチェーンが関与する収量最適化プラットフォームです。
ユーザーはまずデポジット関数を呼び出してスマートプールに一定量の流動性をデポジットし、デポジットのシェアの証拠として Popsicle LP Token (以下、PLP Token) を取得します。 Popsicle Finance は、ユーザーが提供した流動性を Uniswap などの基礎となるプールに預け、収入を得ることができます。
ユーザーは引き出し関数を呼び出して、ユーザーが保有するPLPトークンによって表される流動性シェアに従ってスマートプールから流動性を引き出すこともできます。 Popsicle Finance は、PLP トークンに対応する流動性を Uniswap などの基礎となるプールからユーザーに取得します。
最後に、ユーザーがスマート プールに預けた流動性は、時間の経過とともに一定の利回り (利回り) を生成し、契約のユーザー ステータスに蓄積されます。ユーザーは、collectFees 関数を呼び出して、入金ボーナスの一部を取り戻すことができます。
この攻撃の中核となる機能は、collectFees 機能です。コードを段階的に分析してみましょう。まず、userInfo に保存されているユーザー状態を取得します。ユーザー状態の token0Rewards と token1Rewards は、ユーザーの入金によって蓄積された報酬です。
次に、契約内のスマート プールに対応するトークン ペアの残高を計算します。契約に十分な残高がある場合は、その金額に応じて報酬がユーザーに支払われますが、そうでない場合は、pool.burnExactLiquidity が呼び出されて、基礎となるプールから流動性を取得してユーザーに返されます。
最後に、userInfo に記録された報酬ステータスが更新されます。これを見ると、機関銃プールのコード実装は非常に論理的であることがわかります。しかし、関数の先頭で updateVault 修飾子が見つかりました。この関数はcollectFeesの関数本体の前に実行されます。抜け穴はupdateVault関連関数にある可能性があります。
以上がupdateVault関連機能の実装です。プロセスは次のとおりです。
まず _earnFees を呼び出して、基礎となるプールから累積された Fee を取得します。
次に、_tokenPerShare を呼び出して、token0PerShareStored および token1PerShareStored パラメーターを更新します。これら 2 つのパラメーターは、プール内の各共有によって表される token0 および token1 の数、つまり、スマート プール内の各共有によって表されるトークン ペアの数を表します。
最後に、fee0Earned および Fee1Earned を呼び出して、このユーザーに対応するデポジット報酬 (つまり、user.token0Rewards および user.token1Rewards) を更新します。
上記は、fee0Earned 関数と Fee1Earned 関数の実装です。2 つの関数は同じ実装を持ち、どちらもそのような式を実装します (_fee0Earned を例にします)。
user.token0Rewards += PLP.balanceOf(account) * (fee0PerShare - user.token0PerSharePaid) / 1e18
つまり、この関数は、元の user.token0Rewards とユーザーが所有する PLP トークンの数に基づいて、ユーザーに発行されるべき手数料の割合を計算します。
しかし、この関数はインクリメンタルであることに気付きました。つまり、ユーザーが PLP トークンを保持していない場合でも (PLP.balanceOf(account) が 0)、この関数は user.token0Rewards に保存されているデポジット報酬を返します。
したがって、契約全体に関して、2 つの重要な論理的欠陥が見つかりました。
ユーザーのデポジット報酬は user.token0Rewards と user.token1Rewards に記録され、いかなる形式の PLP トークンや他のものにも関連付けられません。
デポジット収入を取得するために使用されるcollectFees関数は、簿記のuser.token0Rewardsとuser.token1Rewardsの状態にのみ依存し、ユーザーがPLPトークンを保有していない場合でも、対応するデポジット報酬を引き出すことができます。
攻撃プロセスを想像します。
攻撃者はマシンガンプールに一定量の流動性を預け、PLPトークンの一部を取得します。
攻撃者は、collectFees(0, 0) を呼び出します。これにより、攻撃者のデポジット報酬、つまり状態変数 user.token0Rewards の値が更新されますが、実際にはデポジット報酬は取得されません。
攻撃者は、PLP トークンを制御下の他のコントラクトに転送し、collectFees(0, 0) を呼び出して状態変数 user.token0Rewards を更新します。つまり、攻撃者は、PLP トークンを継続的に流通させ、collectFees(0, 0) を呼び出すことで、これらの PLP トークンに対応するデポジット報酬をコピーしました。
最後に、攻撃者は上記のアドレスからcollectFees関数を呼び出して、実際の報酬を取得します。現時点ではこれらのアカウントには PLP トークンはありませんが、アカウントが user.token0Rewards で更新されていなかったため、攻撃者は複数の報酬を引き出すことができました。
この攻撃を現実の例で説明すると、これは銀行にお金を預けることに相当し、銀行は私に預金証明書をくれましたが、この証明書には偽造防止措置がなく、私に拘束されません。証明書のコピーを作成してさまざまな人に送り、それぞれがこの伝票を利用して銀行から利息を引き出しました。
攻撃プロセスの分析
上記のコード分析を通じて、Popsicle Finance のスマート プール実装の抜け穴を発見しました。次に、攻撃トランザクションを詳細に分析して、攻撃者がこの脆弱性をどのように悪用するかを確認します。
攻撃者の全体的なフローは次のとおりです。
攻撃者は 3 つのトランザクション コントラクトを作成しました。そのうちの 1 つは攻撃トランザクションを開始するために使用され、他の 2 つは PLP トークンを受信し、Popsicle Finance スマート プールのcollectFees 関数を呼び出してデポジット報酬を取得するために使用されます。
フラッシュローンを通じてAAVEから多額の流動性を融資します。攻撃者は Popsicle Finance プロジェクトの下で複数のスマート プールを選択し、これらのスマート プールに対応する 6 種類の流動性を AAVE に貸し出しました。
入金、出金、手数料の回収サイクルを実行します。攻撃者は、Popsicle Finance プロジェクトの下で複数のスマート プールをそれぞれ合計 8 ラウンド攻撃し、大量の流動性を引き出しました。
フラッシュ ローンを AAVE に返し、Tornado Cash を通じて利益を洗浄します。
この攻撃トランザクションは主にいくつかの Deposit-Withdraw-CollectFees ループで構成されており、各ループの概略図は上図に示されています。私たちの分析によると、ロジックは次のとおりです。
攻撃者はまずフラッシュローンから借りた流動性をマシンガンプールに預け、一定量のPLPトークンを取得します。
攻撃者は、PLP トークンを攻撃コントラクト 2 に転送します。
コントラクト 2 を攻撃し、SmartGun プールのcollectFees(0, 0) 関数を呼び出して、コントラクト 2 の対応する user.token0Rewards および user.token1Rewards の状態を設定します。
攻撃コントラクト 2 は、PLP トークンを攻撃コントラクト 3 に転送します。
攻撃コントラクト 2 の動作と同様に、攻撃コントラクト 3 はスマート プールのcollectFees(0, 0) 関数を呼び出し、コントラクト 2 の対応する user.token0Rewards および user.token1Rewards 状態を設定します。
攻撃コントラクト 2 は、PLP トークンを攻撃コントラクトに戻します。これにより、マシンガン プールの引き出し関数が呼び出され、PLP トークンが燃焼され、流動性が取得されます。
攻撃コントラクト 2 と攻撃コントラクト 3 は、collectFees 関数を呼び出して、偽の tokenRewards ステータスでデポジット報酬を取得します。
当社の Ethereum トランザクション追跡可視化システム (https://tx.blocksecteam.com/) によると、トランザクション コールの図は次のとおりであり、いくつかの重要なトランザクションは赤色でマークされています。
利益分析
この攻撃による利益の総額: 256,000 WETH、96.2 WBTC、160,000 DAI、539 万 USDC、498 万 USDT、1050 万 UNI、合計 2,000 万ドル以上。
この攻撃の後、攻撃者はまず Uniswap と WETH を通じて攻撃で取得した他のすべてのトークンを ETH に交換し、その後 Tornado.Cash を複数回使用して ETH を洗浄しました。
コアセキュリティテクノロジーを推進する BlockSec チームは、プライバシー コンピューティングに基づく DeFi セキュリティ、デジタル通貨のマネーロンダリング防止、デジタル資産保管に長年取り組んでおり、DApp プロジェクト関係者に契約セキュリティとデジタル資産セキュリティ サービスを提供しています。このチームは 20 以上のトップセキュリティ学術論文 (CCS、USENIX Security、S&P) を発表しており、そのパートナーは AMiner の世界で最も影響力のあるセキュリティおよびプライバシー学者の称号を獲得しています (2011 年から 2020 年に世界で 6 位)。研究結果はCCTV、新華社通信、海外メディアの報道で表彰された。数十の DeFi セキュリティの脆弱性と脅威を独自に発見し、2019 年の国立衛生研究所プライバシー コンピューティング コンペティション (SGX トラック) で世界 1 位を獲得しました。テクノロジーを推進するチームは、オープン性とウィンウィンの概念を堅持し、コミュニティパートナーと協力して安全な DeFi エコシステムを構築します。
QRコードをスキャンして、さらにエキサイティングな情報に注目してください
https://www.blocksecteam.com/
contact@blocksecteam.com