2021年8月4日、Popsicle Financeは攻撃により巨額の損失(2,000万ドル以上)を被りました[1]。 手動分析の結果、これは「ダブルクレイム」攻撃、すなわち報酬システムの脆弱性により、攻撃者が繰り返し報酬を請求できたことが確認されました。 以下では、攻撃トランザクションを用いて、攻撃プロセスと脆弱性の根本原因を説明します。
背景
Popsicle Financeは、複数のチェーン(例:Ethereum、BSC)に対応したイールド最適化プラットフォームです。
具体的には、ユーザーはまずdeposit関数を呼び出して流動性を提供し、Popsicle LPトークン(略称PLP)を取得します。その後、Popsicle Financeがユーザーに代わって流動性を管理し(Uniswapなどのプラットフォームと連携)、利益を生み出します。
ユーザーはwithdraw関数を呼び出してPopsicle Financeから流動性を取り戻すことができ、その量はPLPトークンに基づいて計算されます。
インセンティブ報酬は流動性に由来し、時間とともに蓄積されます。
ユーザーはcollectFees関数を呼び出して報酬を請求できますが、これがこの攻撃の鍵となります。
脆弱性分析
collectFees関数では、token0Rewardとtoken1Reward(対応するLPトークンペアの報酬)がユーザーのために計算されます。計算ロジック全体は単純です。しかし、この関数はupdateVaultというモディファイアを使用しており、これは報酬を適切に更新するために使用されます。


要するに、updateVaultは以下の処理を行います。
- まず
_earnFees関数を呼び出し、プールから蓄積された手数料を取得します。 - 次に
_tokenPerShare関数を呼び出し、token0PerShareStoredとtoken1PerShareStoredを更新します。これらは、シェアあたりのトークン0およびトークン1のプール内の量を示します。 - 最後に
_fee0Earnedと_fee1Earned関数を呼び出し、ユーザーの報酬(それぞれtoken0Rewardsとtoken1Rewards)を更新します。

_fee0Earnedと_fee1Earned関数は同じロジックを共有しており、以下の数式を実装しています(トークン0を例とします)。
user.token0Rewards += PLP.balanceOf(account) * (fee0PerShare - user.token0PerSharePaid) / 1e18
この計算は累積的であることに注意してください。つまり、ユーザーがPLPトークンを保有していなくても、計算された報酬はtoken0Rewardsに格納されている値のままです。
したがって、以下の2つの観察結果が得られます。
- ユーザーの報酬は
token0Rewardsとtoken1Rewardsに格納され、これらはPLPトークンとは関連付けられていません。 collectFees関数はtoken0Rewardsとtoken1Rewardsの状態のみに依存するため、PLPトークンを保有せずに報酬を引き出すことができます。
現実世界では、これはユーザーが銀行にお金を預け、銀行が預金証書を発行するようなものです。残念ながら、この証書は偽造防止機能がなく、ユーザーとも関連付けられていません。 このような場合、複製を作成して他人に配布し、銀行から利益を得ることが可能です。
攻撃フロー
簡潔に言うと、攻撃者は以下の手順で攻撃を実行しました。
- 3つのコントラクトを作成しました。1つは攻撃に使用され、他の2つは報酬を取得するために
collectFees関数を呼び出すために使用されました。 - AAVEから大量の流動性を借り入れるフラッシュローンを利用しました。
- デポジット-ウィズドロー-コレクトFeesサイクルを実行して攻撃を仕掛けました(合計8サイクル実行され、Popsicle Financeの複数のボルトから大量の流動性が引き出されました)。
- フラッシュローンをAAVEに返却し、Tornado.Cashを通じて利益をマネーロンダリングしました。

具体的には、デポジット-ウィズドロー-コレクトFeesサイクルはいくつかのステップで構成されており、当社のオンラインツール [2]を使用することで、簡単にラベル付けして明確に要約できます。

利益分析
合計で、攻撃者はPopsicle Financeから2,000万ドルを収穫しました。これには、2.56K WETH、96.2 WBTC、160K DAI、5.39M USDC、4.98M USDT、10.5K UNIが含まれます。 この搾取の後、攻撃者はまずUniswapとWETHを通じて他のすべてのトークンをETHに交換し、その後Tornado.Cashを使用してマネーロンダリングを行いました。
功労者
Yufeng Hu、Ziling Lin、Junjie Fei、Lei Wu、Yajin Zhou @BlockSec (姓のアルファベット順)
Medium: https://blocksecteam.medium.com/
Twitter: https://twitter.com/BlockSecTeam
連絡先: [email protected]
参考文献
[1] https://twitter.com/defiprime/status/1422708265423556611



