2023-11-13 18:51:57 (UTC) OKC Tokenに対する攻撃がチェーン上で発生し、ハッカーは欠陥のあるMinerPoolを通じてタイムリーな利益を得ました
ハッキングされたトランザクション:
0xd85c603f71bb84437bc69b21d785f982f7630355573566fa365dbee4cd236f08
Hacking Contract 1:
0xD5d8c2fd8A743A89BC497B2F180C52d719a007B9
ハッキング契約2:
ハッキング契約2:
0x617432Fc98c1fFaAB62B8cB94Cef6D75ABD95598
ハッキング契約3:
0x28e7c8337373C81bAF0A4FE88ee6E33d3C23E974
Attacker Address:
次のようになります。0xbbcc139933D1580e7c40442E09263e90E6F1D66D
脆弱性契約:
0x36016C4F0E0177861E6377f73C380c70138E13EE (MinerPool)
攻撃分析
オンチェーンのトランザクションを分析することで、次のようにまとめました。データ分析によって、そのトランザクションを照合し、まとめます。
ハッカーはまず、複数のフラッシュローンを通じて攻撃資金を調達し、合計2,753,399 USDT Tokenを借りました。
その後、これらのUSDTのうち130,000を直ちに換金しました。Tokenは直ちに最小単位のUSDT Tokenと27,264 OKC Tokenに変換されました。
PancakeSwapv2はAMM(Constant Function Market Maker)を使用しているため、プール内の2つのトークンの数の積はモデル内の定数です。これは以下の式で表すことができます:
Which:
- xは取引プールの最初のトークンの数です。
- yは取引プール内の2番目のトークンの数です。
- kはプール内の両方のトークン数の積を表す定数です。
トレーダーがトークンを別のトークンと交換したい場合、プール内の一方のトークン数を増やし(dx)、他方のトークン数を減らして(dy)、一定の価格を維持します。このプロセスにより、トークンの相対価格が変化します。
あるトレーダーがトークンAとトークンBを交換したいとします。
kは一定なので、これはx-yが取引の前後で同じであることを意味します。しかし、トレーダーはトークンAの量を増やし(dx)、トークンBの量を減らす(dy)ので、トークンBの価格は上昇します。
トークンの瞬間価格は、プール内の2種類のトークン数の比率を計算することで導き出せます。トークンAがxでトークンBがyの場合、トークンAに対するトークンBの価格はy/xです。取引後、トークンBのトークン数は減少し、トークンAのトークン数は増加するので、新しい価格は(y-dy)/(x+dy)となります。分子が減って分母が増えると、この比率は小さくなり、トークンBの価格が上がることを意味します。
大規模な取引の場合、dxとdyは非常に大きくなり、価格が大きく動く可能性があります。kを一定に保つためには、dxの増加を補うために大量のdyをプールから取り除かなければならないからです。プール内のトークン数に対する大規模なトランザクションのこの大きな影響は、大幅な価格変動につながります。
そのため、攻撃者は大量のライトニングローン資金を使ってOKCを購入することができ、その結果、OKCの量が減少し、OKCトークンの価格が上昇し、1 OKC = 0.3 USDTの価格が1 OKC = 68.9 USDTに上昇しました
その後、攻撃者は2つの契約アドレスを作成し、それぞれのアドレスに0.01 OKCと0.0001 USDTを送りました。
ハッカーはその後、一次攻撃契約を使用してPancakePair_USDT_OKCプールに流動性操作を追加し、約225,705 LP Token.
を取得しました。style="text-align:centre;">
その後、LPトークンは攻撃者が作成した0x28e7c83373C81bAF0A4FE88ee6E33d3C23E974攻撃コントラクトに転送され、脆弱なコントラクト内のprocessLPReward関数が直ちに呼び出され、コントラクトに格納されたlpHolderアドレスに対する処理が実行されます。攻撃者は次に、脆弱なコントラクト内のprocessLPReward関数を即座に呼び出し、コントラクトに格納されたlpHolderアドレスに報酬を割り当てる。攻撃者はMinerPoolコントラクトに送金するだけですが、コントラクトは送金を受け入れるコールバック関数でprocessLPReward関数を呼び出します。
次の図によると、攻撃契約は次のようになります。0x28e7c83373C81bAF0A4FE88ee6E33d3C23E974は報酬コレクションで77,890 OKC Tokenを受け取った。
その後、攻撃者は攻撃契約0x28e7..E974のLPトークンを転送し、それを破棄してOKCトークンを削除しました。
そして、他の2つの攻撃契約からメインの攻撃契約にすべてのトークンを転送しました
0xD5d8c2fd8A743A89BC497B2F180C52d719a007B9 、それぞれ:272と77,890 OKC Token.
ハッカーはすべてのOKCトークンを転送しました。
最終的に、ハッカーはライトニングローンの元本と利息をすべて返却し、約6,268USDTトークンの最終残高を残し、これらはすべて攻撃者のアドレスに送金されました
。p>
0xbbcc139933D1580e7c40442E09263e90E6F1D66D.
Vulnerability analysis
攻撃の分析を通じて、以下のことがわかりました。ハッカーの主な利益は、MinerPoolコントラクトのprocessLPReward関数によって作られることが分かっています。この関数のロジックは、lpHolderを取得し、それが含むLPの数に応じて直接かつ比例的に報酬を与えることです。
このロジックから、addHolder関数がextcodesize()を使用してアドレスの現在のサイズを計算し、addHolder関数がaddHolder()を使用するかどうかを決定していることがわかります。しかし、攻撃者がCREATE2を使用してコントラクトを作成する場合、コントラクトが初期化されてもアドレスのサイズは0のままであるため、攻撃者はコンストラクタ内でこの関数を呼び出すことで、コントラクト呼び出しの制限を回避することができます。
譲渡時にaddHolder関数が呼び出され、契約アドレスがlpHolderリストに追加されました。
processLPReward関数のコードのロジックを分析すると、下図からわかるように、報酬を受け取るためのロック時間は設定されているものの、LPの保持時間をチェックしたり制限したりする設定はされていないため、ハッカーはライトニングローンによって一時的に大量の資金を手に入れ、LPと交換し、報酬を受け取った後すぐに破棄している。報酬を受け取った後、すぐに破棄する。
Summary
簡単に言えば、ハッカーはライトニングローンを通じて大量のUSDTを借り、それを大量のOKCと交換し、OKCの価格を吊り上げた。また、OKCプロジェクトはLP報酬のリリースにロックアウト条件を設定していなかったため、ハッカーは報酬を得た後すぐに流動性を引き出し、プロジェクト側が発行した流動性提供者の報酬を得た。ハッカーはOKCプロジェクトから報酬を得たOKCトークンを売却した。最終的な利益は6,268USDT.