今回は、バイナンススマートチェーン(BSC)のUranium Financeで規模が大きいハッキング事件が起こったので、解説を加えていこうと思います。
今回の記事を書くにあたって、個人的に今読んでいただいているみなさんにこの事件をもとに今後の対策を知ってもらい自分の資産を守ることにつなげてほしいと思っています。
ぜひ最後まで読んでいただいて、今後の運用に役立ててください。
この記事の目的・注意事項
諸注意ですが、この記事では「大変な事件が起こったね!」という話をしたいわけではなくこの事件を通して防御力を上げてもらうことが目的です。
今DeFiのサービスでは新しいネットワークができたりと、どんどん拡大していますがその拡大に伴ってユーザーが増え悪いことを考える人も当然増えます。今後トラブルや事件に巻き込まれる可能性はなくは無いので、できるだけ知識をつけて自分の資金を守れるようになってください。
ちなみに今回の事件では既に$500万(日本円で54億円)の資金が抜かれています。現在いろんな人の協力のもと対策や対応が進んでいるようです。
そしてこの記事を書くにあたって自分なりに調べたのですが、読み込みが不十分なところがあるかもしれません。なので「この記事に書いてあるから全て正解だ」と思わずに「もしかしたら違うかもしれないから自分で調べてみよう」など自分自身で動くことを意識してもらえたらと思います。
今回の事件から学べる被害対策
今回日本円で54億円というかなり大きい金額が飛んだのですが、Twitterなどで調べてみても「3000万いかれました」など、大きい金額での被害を受けている話が上がっていました。
なので、「ここは守っておいた方がいいポイント」を今から解説していくので、DeFi初心者の方は是非読んでもらえたらと思います。
1. 消えたらまずい資金でDeFi/CeFiをやらない
2. 一点集中でステークしない
3. 新台特攻したいなら知識をつける
4.「migrate無し」「タイムロック有り」など新しいファームに参加する際のルールを決める
5. 参加しているファームのtelegramやdiscordには参加する
1. 消えたらまずい資金でDefi/CeFiをやらない
「このお金がなくなったら生活ができない」というお金でDeFiをやらないことが大事です。実際にUraniumのテレグラムで「すべての貯金・生活費を全突っ込みして、もう生活ができません」というふうになっている外国人の方などいたので、消えたらまずいお金でDeFiはやらないことを強くお勧めします。
もちろん無くなっていいお金を持っている人はいないと思いますが、無くなっても生活に支障が出ない範囲でやってもらえたらと思います。
2. 一点集中でステークしない
人間なので、いろんなDeFiに分散して入れていると、だんだん利率がいいところに入れたくなってきます。
例えば、1千万円あるとして10個に100万円ずつ分散入れる人と、利率が一番いいところ1個に全部入れちゃおう!という人がいますが、後者は今回みたいなトラブルが起きたときに一発で全部持っていかれるので、一点集中しないことが重要です。
3. 新台特攻したいなら知識をつける
新台特攻とはざっくり言うと「新しいファーム・プール」のことをいいます。
すぐにでも新台特攻したいなら、絶対に知識をつけるべきだと思っています。基本的に新しいファームやプールが本当に安全なのかどうかははっきりわかりません。
また今回の事件はセキュリティの穴を突かれたわけですが、仮に穴を突かれなかったとしても、運営がトークンを売ったり、大口のユーザーがトークンを売ったりすることでトークン価格が下がる「Dump」という状態が起きる可能性もあります。
このように、今後どれだけけセキュリティがしっかりしてきてもそう言った被害に巻き込まれる可能性はみんな等しくあります。
なので新台特攻したい場合は知識をちゃんとつけるようにしましょう。
4. 「migrate無し」「タイムロック有り」など、新しいファームに参加する際のルールを決める
参加する際のルールは絶対に決めておいた方がいいです。
実を言うと2ヶ月くらい前までは「migrateがあるない・タイムロックあるない」で多くのユーザーが過敏に反応していて、パトロールのようなものまでありました。
むしろ最近では「migrateないのが普通だよね」「タイムロックあるのが普通だよね」という状態が標準化してきて、この辺りの「あるない」の確認を誰もしていないなあという印象があるので、自分で「migurate・タイムロックのあるない」を確認するようにした方がいいと感じています。
5. 参加しているファームのtelegramかdiscordには参加する
今回のUraniumの件も含めて、ハッキングが起きてからファームのグループに参加する人が意外といます。
例えば、「どんどんトークンの価格が落ちてるぞ?どうなっているんだ?」と気づいた人がTelegramに参加して、そこで初めて3時間前にハッキングされていたと気づくケースがあります。
また、こういったグループには通称「ラグプル警察」と呼ばれるユーザーがいて「このファームはmigrateコードがあるぞ」「ここはラグプル(rugpull)だぞ」みたいにパトロールして教えてくれているユーザーがいます。こういう人のおかげで危ないファームに資金を突っ込むことを止めることができます。
ただ、彼らが本当のことを言っているかどうかもわかりませんし、中にはいろいろネガティブなことを批判されていたけどうまくいっているファームもあるので、グループに参加しつつ各自で知識をたくわえて対策できるようになりましょう。
ハッキングの概要・被害
先に言っておきますが、私自身Uranium Financeをやっていたわけではありません。実を言うと、前からUranium Financeが話題になっていたのでやろうかなと思っていました。
ただ、前に一度サイトがハッキングされて、その後ハッキングされたのかされていないのか中途半端な状況になり、いつの間にか復活していた…という曖昧な感じになっていたので「なるほどなもうここはやらないでおこう」と判断しました。
そして最近になってまた話題になり、質問も結構きていたので触り方だけ解説をやろうかなと思っていた矢先、2度目の被害が発生した。という感じでした。
なので、実際に運用していたわけではありませんが、今回被害状況などを公式サイト・ニュースサイト・Twitterなどで情報収集したので、この記事で解説していきたいと思います。
まず下の画像はUraniumの流動性のコントラクトのトランザクションになります。
BUSDとADAのペアなんかはガバガバに抜かれているという感じです。こんな感じで他のペアもやられていて、合計で50000万ドル分(日本円で約54億円分)持っていかれました。
この画像のページ(トランザクション)は実際に誰でも見ることができるので、できれば見ておくことをお勧めします。というのもどんな感じで資金が抜かれていくのか?や、犯人のウォレットアドレスのコントラクトを見ることもできるので勉強になるかと思います。
何が起こったのか?
ここからはさらに細かく説明していきます。
かなり専門的な内容になるので、この部分は正直読まなくても大丈夫です。最後の「まとめ」の項目に重要だと思ったことを書いているのでここは飛ばして読んでいただいて構いません。興味のある方だけ読んでいただけたらと思います。
まず「何が起こったのか?」ということに関してですが、V2からV3に移行したときにコードに穴ができました。
V2からV3に移行したと言っていますが、具体的にはUraniumLPやUraniumFactoryというSwapやDEXの取引所の機能の部分をアップ デートしました。ですがその際に穴ができてしまったということになります。
今回のトラブルが起きた箇所は下の画像の赤線(10000)と緑線(1000の2乗)のところになります。
元々このUraniumはUniSwapというものをフォークして作ったそうですがUniSwapは1000,1000,1000の2乗、Pancakeは10000,10000,10000の2乗、今回のUraniumのV2は10000,10000,1000の2乗となっています。(下記画像参照)
ちなみにUranium FactoryやUraniumのLP RADSLPですべて確認できます。これは取引所の機能でいうところのSWAPになります。トークンの交換のプログラムの一部です。
続いて下の画像のUraniumのV1・V2・V2.1をそれぞれ比較してみると、V1は1000,1000,1000の2乗だったのでバグは起こっていませんでした。
ですがV2に移行した際にトラブルが起こったので、V2.1では、10000,10000,1000の2乗の部分を変数に変えていることがわかります。変数に変えたことで書き換え漏れがないのでおそらくこの部分を修正したんだろうと思われます。
ただ、これに関してTwitterやTelegramなどでは「意図的なんじゃないか?」と言っている人がちらほらいたので次の項目でこの疑問についてまとめました。
疑問点
- マジックナンバー(数字直打ち)おかしくない?
- 内部犯行では?
- 普通あの箇所変更しなくない?
1. マジックナンバー(数字直打ち)おかしくない?
確かに変数を打った方がいいですが、フォーク元のUniswapも直打ちなので意図的なものではないと思います。
先ほどの画像にもあったように数字の部分が直打ちしてあるのですが、確かにこれはエンジニア界隈では「普通やらないよね?」と思うやり方です。なぜなら今回のようなトラブルが起こるからです。(数字を変えたら他のところも変えなきゃいけないのに、変え忘れる人為的ミスが起こりトラブルが発生するため)
ただ、フォーク元のUniswapも数字は直打ちです。なのでUniswapの時点で本当はダメだったというだけで、Uraniumを開発した人が深く考えてやっていないだけじゃないかな?と思います。
2. 内部犯行では?
「V2からV2.1に移行します」とアナウンスが出てすぐにハッキングされて、その後該当箇所が修正されたので、内部犯行なのでは?と疑っている人もいました。
確かに話の流れがスムーズなのでそのようにも見えます。ただ、実行内容自体は技術的に誰でも可能です。V2.1移行の話も内部のエンジニアはこの箇所のミスに気付いていただけかもしれません。
ただここに関しては追加で事実情報が出てこないとあくまで予測しかないのであまり詳細な話はできないかなと思っています。
3. 普通あの箇所変更しなくない?
今回Uranium Financeは手数料を0.2%から0.16%に下げました。なので手数料率の変更に伴って必要な変更になります。連動している部分の変更し忘れといったイメージです。
少し詳しく説明すると、まずUraniumのV1の一番上には「balance0Adjusted」と書かれています。これは「balance0を1000倍にして手数料0.2%分を引く」という数式です。
これだけを見ると「普通に0.002倍にすればいいじゃないか」と思うかもしれないですが、あのプログラムの中では小数点ってものを扱うと少し数字がおかしくなることがあるので、「全部一回整数に戻してから計算する」というパターンがあります。
なので、0.2%を表現したいなら1000倍にします。すると1の位が0.1%の単位になるのでこれで計算すると、今回0.2%から0.16%にしたのでもう一桁必要になりました。そしてV2ではそこが反映されることになりました。
そして、V2では移行に伴い10000倍して16引くという計算が必要になりました。ただ、V2の赤文字で書かれている10000の部分を変えた時に、右下にある1000**2も変えないといけなかったのですが、変え忘れが起きました。その結果、ガッツリ資金を持っていかれてしまいました。
本当にちょっとしたことですが、これだけの差でかなりの金額でトラブルが起きてしまうので、エンジニアの仕事というのはとても大変だなと思います。
ざっと詳細を話しましたが「普通あの箇所変更しなくない?」という意見は、確かに動いているから変更しないことはわかりますが、今回は手数料を変えることになったので、変更することになったという感じです。
シミュレーション
今回の事件でが「どのようにして起こったのか?」実際にシミュレーションをしていきます。
手口としてはDEX(取引所)に対してBUSDとADAの2つを一番小さい単位で送ります。その代わりにDEXからBUSDとADAを両方とも抜きとるというやり方です。
BscScanでトランザクションを見てみると、かなりの金額が持っていかれていることがわかります。
ここから「どうやって抜き取ったのか?」その手口を解説していきます。数字が小さい方がわかりやすいので下の画像をもとに解説します。
先ほども言ったようにこれからシミュレーションでやっていく手口としては、DEX(取引所)に対してBUSDとADAの2つを一番小さい単位で送り、その代わりにDEXからBUSDとADAを両方とも打ち抜くというやり方です。
下の画像はUraniumのV2のスワップの部分です。少し見にくいですが今からこれを実際に見ていきます。
まず上部にamount0Out(BUSD)、amount1Out(ADA)とあります。(下記画像赤線↓)
そしてこの2つを出力するプログラムを投げます。
次にreserve0、reserve1とありますが、reserveというのは「取引所内の交換できるトークン数(残高)」を意味します。
そして右側の黄色の枠内を見ると残高がわかります。BUSDが63808でADAが84754となっています。
続いてamount0Out(BUSD)について説明します。まずsafeTransferとありますが、これは「先に取引所からトークンを送る処理の予約」を意味します。その後ろにはtoとありますが、これは犯人のアドレス先を意味していて、この先にある犯人のアドレスに57428BUSDを送ることになります。(amount1Out(ADA)も同じ流れ。76279ADAを送る。)
次にbalance0を見てみます。ここでいう「balance」というのは取引所内の残高の計算を意味します。計算式としては元々の「63808」に最小単位の1を送ったので「+1−57428」となります。(balance1も同じように計算します)
続いてbalance0Adjustedでは「その手数料分を差し引いても、ちゃんとトークン交換ができるのか?」を見ることができます。
ここでは先ほどの計算式ででた「6381」を10000倍して0.16%分を引くという計算をします。(balance1Adjustedも同じように計算します。)
続いて「手数料差し引いたら交換できないんじゃないか?」というチェックです。ぱっとみ数式がバァっと並べられているだけのように見えますが、よく見ると左側の方が大きいことがわかります。なので今回は通過します。
ただ、本来だとこれは通過しません。何故通過しないかというと緑矢印の部分を見るとわかります。今回1000の2乗は人為的なミスでやってしまっているので数式は左側が大きくなっていますが、本来は10000の2乗なので、計算式は1000ではなく0が2つ増えて100000になるはずです。
すると10の17乗になるので、右側が大きくなり処理が停止します。処理が停止するとここまでやった内容の全てがロールバックされる(元の状態に戻される)ことになります。
ただ、今回に限ってチェックが通過しスワップが成り立ってしまい取引所残高の90%に相当する金額を出せる仕組みになってしまっていました。
なので、流動性の中の残高がわかればその90%を何回も何回も出力させているという感じになっています。100万円あったとしたらそのうちの90万円を抜き取り、次に残り10万円から9万円を抜き取り、次に残り1万円から9000円を抜き取り、次に1000円・・・と言った感じでずっと繰り返し出力されていました。
なので、BscScanでトランザクションを見るとわかりますが、トランザクションがとにかくたくさん表示されます。(参考ページ:BscScan)
まとめ
今回はコードを見ながら解説していきましたが、コードに原因があるかもしれないからといって自分が新しいファームを見つけたときにコードを一つ一つ見ないといけないのか?と不安になる人もいるかもしれません。
ただ正直それは現実的じゃないですし、無理な話なのでファームに参加するときは「ステーキング先がハッキングされる可能性は0じゃない」と考えながらやるようにするしかありません。
それともう一つ私も含めてですが、情報発信している人も調べられる範囲には限界が必ずあります。今回のハッキングもおそらく予期しなかった人の方が圧倒的に多いです。なので、悪意を持って情報発信をしているわけではないということを理解してもらった方がいいと思います。
あくまで自分が参加してて、なおかつ情報を欲しがっている人がいるからYoutubeやTwitterで発信しとこうぐらいの感じだと思います。
本当であれば今回の記事のようにコードなども見て「ここは危ないですね。ここは安全ですね。」って言えるところまで細かく調べて発信できるのが一番いいですが、それだと時間もかかりますし専門的な知識を持っていないとわからないので現実的ではありません。
なので、発信者の情報を鵜呑みにせずあくまでも自分主体で判断して運用していきましょう。
感想
個人的に今回の事件は衝撃で、これは今後運用していく中でとても重要だなと思ったことがありました。
今回扱ったUraniumFinanceではV1からV2への移行で事件が起きました。イメージとしては、新しい台がハッキングされるわけではなくV1からV2に場所が移動した時にハッキングされたという感じだったので、V1でうまくいっていたファームだったとしてもV2になった時にラグる可能性があることが証明されました。
なので、もしかしたら今後同じようなパターンでラグるファームが増えてくるんじゃないか?と正直思っています。
V1が調子良かったからどこかのタイミング手数料を下げます!と言ってV2に移行させるとして、ユーザーもV1での安心感や信頼感をみんな感じているので「全然いいよ!」となります。その時にハッカーはセキュリティホールを作っておいて、どんどんユーザーが参加したタイミングで資金を引き抜くことができたので、今回の事件を頭に入れて今後も注意しないといけないと感じました。
とはいえ、V2に移行すればコントラクトも変わりますしRouterもFactoryも変わるので新規ファームと同じように扱わないといけないはずなんですね。ただ、V1である程度うまくいっているところだと移行しようが信用しちゃうことがあるので、今回は良い勉強になったなと思います。
これからも3MIKANでは仮想通貨に関する情報などを発信していきます。Youtube動画もアップしているので、動画の方がわかりやすいという方はぜひ見てみてください。(Youtube: 3MIKAN チャンネル)
最後まで読んでいただきありがとうございました。