
コードを通じてDeFiにおける裁定機会を特定する
TechFlow厳選深潮セレクト

コードを通じてDeFiにおける裁定機会を特定する
本稿では、一部の分散型取引所およびアグリゲーターがスマートコントラクトコードにおいて潜在的に存在する裁定取引の機会について分析する。
概要
分散型金融(英語:Decentralized finance、通称DeFi)はブロックチェーン上に構築された金融であり、証券会社、取引所、銀行などの金融機関を通じて金融商品を提供するのではなく、ブロックチェーン上のスマートコントラクトを利用して金融活動を行う。DeFiには清算や価格差による裁定取引など、多数の裁定機会が存在する。本稿では一部の分散型取引所(DEX)およびアグリゲータ(Aggregator)のスマートコントラクトコードにおいて潜在的に存在する裁定の可能性について分析する。
分析
Uniswap
Uniswapは自動マーケットメイカー(AMM)モデルを採用した分散型暗号資産取引プラットフォームであり、現在主流のバージョンとしてUniswap V2とUniswap V3がある。以下でそれぞれに存在する可能性のある裁定の機会を分析する。
Uniswap V2 Router
Uniswap V2では、ユーザーは通常Routerコントラクトを通じてPairコントラクトおよびFactoryコントラクトとやり取りする。一般にRouterは取引中のトークンの中継を行うだけで、トークンを保持しないが、エアドロップや送金ミスなどの理由により、Routerコントラクト内に特定のトークンが残存している場合がある。これらのトークンをどのように引き出すことができるか。
Uniswap V2 Router 02コントラクトのコードを分析すると、removeLiquidityETHSupportingFeeOnTransferTokens関数が存在することがわかる。

この関数はWETHを含む流動性の一方を引き出すために使用され、内部でremoveLiquidity関数を呼び出す際にtoアドレスとしてaddress(this)を指定している。つまり、両方のトークンがまずRouterコントラクトに移転され、その後Routerコントラクトから指定されたアドレスに再び移転される。ここでWETHの数量はremoveLiquidityの返り値に基づくため変更できないが、もう一方のトークンの数量はbalanceOf(address(this))、すなわちRouterコントラクト内の当該トークン残高となる。
したがって、上記の分析から以下の裁定プロセスが導き出せる。
-
Router 02コントラクトにERC-20トークンが存在することを監視する;
-
addLiquidityETHを呼び出して当該ERC-20トークンとWETHの流動性を追加する;
-
removeLiquidityETHSupportingFeeOnTransferTokensを呼び出して流動性を引き出す。
制限事項:
-
もしそのトークンが以前WETHとペアを組んでいなかった場合、初回の流動性追加時にわずかな流動性(MINIMUM_LIQUIDITY)が失われる;
-
現時点ではRouter 02コントラクト内のWETHおよびETHを引き出す方法は見つかっていない。
Uniswap V2 Pair
Uniswap V2 Pairコントラクト、すなわちいわゆる流動性プールは、流動性を提供する2種類のトークンを保持しており、balanceOf(address(this))ではなくreserveを使って残高を記録している。そのため、誰かが誤って流動性トークンを直接コントラクトに送金すると、balanceとreserveの間に差異が生じる。Pairコントラクトにはskimというバランス調整関数が存在し、この関数を呼び出すことで差額分のトークンを引き出すことができる。

この関数は流動性プール内の両方のトークンについて、balanceとreserveの差額をtoアドレスに送金することが確認できる。
また、流動性プールには誤送金やエアドロップなどの理由で、その2種類以外のERC-20トークンが存在する場合もある。これらはどのように引き出せるか。
Pairコントラクトのコードを分析したところ、それらのトークンを引き出す手段は見つからない。ただし一つの例外がある:流動性プール内にそのプールのLPトークンが存在する場合である。
このような場合は、Pairコントラクトのburn関数を呼び出し、流動性を削除して対応する2種類の流動性トークンを取り出すことができる。

Uniswap V3 SwapRouter
Uniswap V3のSwapRouterコントラクトもUniswap V2 Router同様、ERC-20トークンおよびETHが存在する可能性がある。幸運にも、SwapRouterコントラクトにはそれらのトークンを簡単に引き出すためのいくつかの関数が提供されている。
ERC-20トークンの引き出しにはsweepToken関数を使用できる。

ETHの引き出しにはrefundETH関数を使用できる。

また、unwrapWETH9関数を直接呼び出してWETHをETHに変換して引き出すことも可能である。

以上がUniswap V3 SwapRouterコントラクトに対する裁定分析である。
Uniswap V3 Poolコントラクトのコードを分析した結果、他のトークンを引き出す手段はなく、Uniswap V2 Pairコントラクトのようにbalanceとreserveに差異が生じる状況もないことが判明した。
SushiSwap
SushiSwapは当初Uniswapのフォークプロジェクトとして始まり、後に独立したエコシステムへと発展し、さまざまな金融サービスや製品を提供している。
SushiSwapはUniswap V2と同様の設計であるため、前述のUniswap V2向け裁定手法はSushiSwapに対しても適用可能である。
SushiXSwap
SushiXSwapはSushiSwapがLayerZeroを基盤に開発した全チェーン間取引プロトコルであり、Optimism、Arbitrum、Fantom、BNB Chain、Polygon、Avalancheなどのネットワークをサポートしている。ユーザーはサポートされるネットワークおよび資産間でクロスチェーン取引を行うことができる。
SushiXSwapコントラクト内のトークンをどうやって引き出すか。
SushiXSwapの主な機能はcook関数によって実装されており、一連の操作をサポートしている。サポートされる操作リストは以下の通り。

その中のACTION_DST_WITHDRAW_TOKEN操作のコード実装は以下の通り。

まずcook関数に渡されたdataをデコードし、amountが0かどうかを判定する。0の場合、amountの値は当該コントラクト内のERC-20トークン残高またはETH残高に設定される。最後に_transferTokensを呼び出して、指定されたアドレスにトークンを送金する。

したがって、actionsにACTION_DST_WITHDRAW_TOKENを設定し、data内に送金したいトークン、受信アドレス、数量を構築すれば、SushiXSwapコントラクト内のトークンを引き出すことができる。
Sushi BentoBox
Sushi BentoBoxはSushiSwapエコシステムのコンポーネントの一つであり、高度に柔軟な分散型金融(DeFi)金利最適化製品である。簡単に言えば、ユーザーが資産を預け入れたり借りたりして利子を得られるスマートコントラクトプラットフォームであり、DeFi領域での収益を最大化することを目的としている。
イーサリアム上のBentoBoxコントラクトには大量のトークンが保存されているが、このコントラクトには裁定の余地があるだろうか。
BentoBoxコントラクトでは、ユーザーはdeposit関数を使って預入操作を行うことができ、その実装は以下の通り。

ユーザーはトークンアドレス、支払い元アドレス、受取アドレス、数量、株式数を指定して関数を呼び出し、一連の検証後、amountまたはshareを変換する。重要なのは195~198行目の検証処理であり、amount <= _tokenBalanceOf(token).sub(total.elastic) という条件がある。
BentoBoxコントラクトでは、あるトークンの残高はtotal.elasticで記録されており、これはUniswap Pairコントラクトのreserveに似ている。特定の状況下では_tokenBalanceOf(token)との間に差異が生じることがあり、deposit関数のこの特性を利用することで、その差額部分を実質的に自分のBentoBox内残高に変換できる。
したがって、パラメータを指定する際、差額が存在するトークンのアドレスをtokenに設定し、amountにその差額を設定し、fromをBentoBoxコントラクトのアドレスに、toを自分のアドレスに設定する。207行目では、fromアドレスがBentoBoxコントラクト自身であるため、実際に送金は行われず、total.elasticと_tokenBalanceOf(token)の値だけが調整され、toアドレスのコントラクト内残高として反映される。
DODO
DODOは分散型取引プラットフォームであり、独自のアクティブ・マーケットメイキング(PMM)アルゴリズムを用いてWeb3資産に効率的なオンチェーン流動性を提供する。DODOは自ら流動性を提供するだけでなく、他の取引所の流動性もアグリゲートする。
DODOには一連のコントラクトがあり、ユーザーは通常DODO V2 Proxy 02コントラクトを通じてトークン交換を行う。UniswapのRouterコントラクトと同様、このコントラクトにも何らかの理由でトークンが残っていることがある。これらのトークンをどのように引き出すか。
DODO V2 Proxy 02
DODO V2 Proxy 02コントラクトにはexternalSwap関数が存在し、DODOがアグリゲートする外部プラットフォーム(例:0x、1inch)を呼び出して交換を行う。その実装は以下の通り。

1719~1721行で入力パラメータの検証を行い、1724行でfromTokenがETHかどうかをチェックする。そうでない場合、呼び出し元のトークンがコントラクトに送金され、承認処理が行われる。DODOAPPROVEコントラクトのコードを分析した結果、fromTokenAmountを0に設定すれば検証を回避できることを確認した。

次に、呼び出す外部コントラクトがホワイトリストに含まれているかを検証する。swapTargetおよびcalldataConcatはユーザーが制御可能なため、swapTargetを0xまたは1inchのコントラクトアドレスに、calldataConcatを当該コントラクトのview関数のエンコードデータに設定することで、戻り値をtrueにし、後続のrequire検証を通過できる。

次に、コントラクト内のtoTokenがすべて呼び出し元に送金される。toTokenはERC-20トークンまたはETHのいずれかであり、送金後に最小期待数量の検証が行われるが、minReturnAmountを非常に小さな値に設定すれば通過できる。最後の二つの関数呼び出しは重要ではない。

以上の手順により、DODO V2 Proxy 02コントラクト内のERC-20トークンおよびETHを引き出すことができる。
1inch
1inchは複数のDEXから流動性を集約する分散型取引所(DEX)アグリゲータであり、ユーザーに最良のトークン交換レートを提供する。異なるソースからの流動性を統合することで、1inchはユーザーの取引を最適化し、各プラットフォーム間で最も有利な価格を見つける支援を行う。1inchのスマートコントラクトは自動的に複数の分散型取引所間で取引を実行し、ユーザーが容易に最良の価格と最低のスリッページを得られるようにする。さらに、流動性マイニングやガバナンストークンなど他の機能も提供している。
1inchの主要コントラクトはAggregationRouterであり、現在広く使われているのはV4およびV5バージョンである。これらのコントラクトも何らかの理由でトークンを保持していることがあり、関数に渡すパラメータを適切に構築することで、コントラクト内のトークンを引き出すことができる。
AggregationRouterV5
AggregationRouterV5コントラクトにはswap関数が存在し、その実装は以下の通り。

desc内のminReturnAmountを検証した後、srcTokenおよびdstTokenを取得し、986~997行ではdesc構造体内のflagsおよびsrcTokenを巧みに構築することで検証を回避できる。

次に_execute関数を実行する。ここではcall呼び出しが行われ、実行ステータスが検証されるが、executorはユーザーが指定するため、0アドレスを使用することで検証を回避できる。

次にコントラクト内のdstToken残高を取得する。1007~1018行では、desc内のflagsおよびminReturnAmountを巧みに設定することで検証を回避できる。

最後に、コントラクト内のdstToken残高がすべてdstReceiverアドレスに送金される。このアドレスもユーザーが制御可能である。

以上の手順により、swap関数に渡すパラメータを構築することで、AggregationRouterV5コントラクト内のトークンを引き出すことができる。
AggregationRouterV4
AggregationRouterV4はAggregationRouterV5とほぼ同じであり、swap関数も存在し、実装は以下の通り。

AggregationRouterV5のswap関数と実装が同一であり、V5ではcallの最適化が施されているのみであるため、AggregationRouterV5と同じ方法でAggregationRouterV4コントラクト内のトークンを引き出すことができる。
まとめ
本稿では一部の分散型取引所およびアグリゲータについて簡潔に紹介し、それらに潜在する裁定の可能性について、スマートコントラクトコードの観点からその原理を分析した。しかし実際の成功にはGAS代、ノード速度など多くの要因が関係する。
TechFlow公式コミュニティへようこそ
Telegram購読グループ:https://t.me/TechFlowDaily
Twitter公式アカウント:https://x.com/TechFlowPost
Twitter英語アカウント:https://x.com/BlockFlow_News














