通過代碼看出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 返回的,無法修改,但是轉移的另一種Token 的數量是balanceOf(address(this)),即Router 合約中的該代幣的餘額。

因此根據上述分析,我們能得到一個套利的流程:

監控到Router 02 合約存在ERC 20 代幣;

  • 監控到Router 02 合約存在ERC 20 代幣;

  • 調用addLiquidityETH 添加該ERC 20 代幣和WETH 的流動性;

  • 調用removeLiquidityETHSupportingFeeOnTransferTokens 移除流動性。

局限性:

  • 如果該代幣之前沒有和WETH 組流動性,當第一次添加流動性時會損失一小部分流動性(MINIMUM_LIQUIDITY);

  • 暫時未發現提取Router 02 合約中的WETH 和ETH 的方法。

Uniswap V2 Pair

Uniswap V2 Pair 合約,即所謂的流動性池,存儲著提供流動性的 2 種代幣,因為Pair 合約中使用的是reserve 來記錄餘額而不是balanceOf(address(this)),因此有人直接誤轉流動性代幣到合約中時會出現balance 和reserve 出現差值,而Pair 合約中存在平衡函數skim,我們可以調用該函數將這差值數量的代幣給提取出來:

通過代碼識別DeFi中的套利機會

可以看到該函數會將流動性池中兩種流動性代幣的balance 和reserve 差值數量的代幣轉移到to 地址。

流動性池中除了這兩種代幣外,也會因為誤轉、空投等原因存在其他的ERC 20 代幣,如何提取這一部分的代幣呢?

對Pair 合約的代碼分析後發現無法提取這一部分代幣,只有一種情況例外:當流動性池中存在該池的LP 代幣時。

出現這種情況我們可以調用Pair 合約的burn 函數,移除流動性,取出相應的兩種流動性代幣:

通過代碼識別DeFi中的套利機會

Uniswap V3 SwapRouter

Uniswap V3 的SwapRouter 合約中也會存在和Uniswap V2 Router 一樣的情況,存在ERC 20 代幣和ETH,但是幸運的是SwapRouter 合約提供了幾個函數可以方便提取其中的代幣。

提取ERC 20 代幣我們可以使用sweepToken 函數:

通過代碼識別DeFi中的套利機會

提取ETH 我們可以使用refundETH 函數:

通過代碼識別DeFi中的套利機會

也能夠直接調用unwrapWETH 9 函數將WETH 還原成ETH 並提取出來:

通過代碼識別DeFi中的套利機會

以上是對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 函數實現,該函數提供了一系列的操作,支持操作列表如下:

通過代碼識別DeFi中的套利機會

其中有一個操作ACTION_DST_WITHDRAW_TOKEN,其代碼實現如下:

通過代碼識別DeFi中的套利機會

首先將傳入cook 函數的data 進行解碼,然後判斷amount 是否等於 0 ,等於 0 則將amount 的值設為該合約的ERC 20 代幣的餘額或者ETH 的餘額。最後調用_transferTokens 將代幣轉移到指定的地址:

通過代碼識別DeFi中的套利機會

因此我們只需要構造傳入cook 函數的actions 和datas,即將actions 設置為ACTION_DST_WITHDRAW_TOKEN ,在data 中構造想要轉移的代幣、接收地址、數量,即可轉移出SushiXSwap 合約中的代幣。

Sushi BentoBox

Sushi BentoBox 是SushiSwap 生態系統中的一個組件。 BentoBox 是一個高度靈活的去中心化金融(DeFi)利率優化產品。簡單來說,它是一個允許用戶存儲、借用和賺取利息的智能合約平台。 BentoBox 的主要目的是優化用戶在DeFi 領域中的收益。

以太坊上的BentoBox 合約中存儲了大量了代幣,那麼該合約是否存在套利的空間呢?

在BentoBox 合約中用戶可以通過deposit 函數進行存款操作,函數的實現如下:

通過代碼識別DeFi中的套利機會

可以看到用戶傳入指定的代幣地址,扣款地址,接收地址,數量,股份數量,函數首先做了一系列校驗,然後將amount 或者share 進行轉換,關鍵點在195 – 198 行,這裡做了一個校驗:amount

在BentoBox 合約中某種代幣的餘額使用的是total.elastic 來記錄,類似Uniswap Pair 合約中的reserve,某些情況下會和_tokenBalanceOf(token) 產生差值, 我們可以利用deposit 函數這裡的特性,將差值部分真實轉換成自己在BentoBox 合約中的餘額。

因此我們傳入參數時將token 設置為存在差值的代幣地址,將amount 的值設置為差值,然後將from 設置為BentoBox 合約的地址,將to 設置為自己的地址,在207 行時由於地址為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,代碼實現如下:

通過代碼識別DeFi中的套利機會

1719-1721 行在對傳入的參數做校驗,然後 1724 行校驗fromToken 是否為ETH,不是的話則會將調用者的代幣轉移到合約中,然後進行授權,在分析了DODOAPPROVE 合約的代碼後發現只需要將fromTokenAmount 設置為 0 即可繞過:

通過代碼識別DeFi中的套利機會

然後會對調用的外部合約做校驗,是白名單內的才能夠調用,這裡的swapTarget,calldataConcat都是由用戶可控的,因此可以將swapTarget 設置為0x 或者1inch 的合約地址,然後calldataConcat 設置為其合約的view 函數的編碼,從而讓返回的值為true,也能通過後面的require 校驗:

通過代碼識別DeFi中的套利機會

接下來會將合約中的toToken,全部轉移給調用者,這裡的toToken 可以是ERC 20 代幣,也可以是ETH,發送完後會進行最小的預期數量校驗,我們將minReturnAmount 的值設置為非常小的值即可通過。最後兩個函數調用無關緊要。

通過代碼識別DeFi中的套利機會

通過以上的步驟我們就能夠提取出DODO V2 Proxy 02 合約中的ERC 20 代幣以及ETH。

1inch

1inch是一個去中心化交易所(DEX)聚合器,它從多個DEX 中匯集流動性,以便為用戶提供最佳的代幣兌換價格。通過整合來自不同來源的流動性,1inch幫助用戶優化交易並在各個平台之間找到最優惠的價格。 1inch的智能合約自動在各個去中心化交易所之間進行交易,使用戶能夠輕鬆地在不同交易所之間獲取最佳價格和最低滑點。此外,1inch還提供了其他功能,如流動性挖礦和治理代幣。

1inch 的主要合約是AggregationRouter,現在使用較多的是V 4 和V 5 版本,這兩個合約也會因為各種原因存在一些代幣,我們可以通過構造的傳入函數中的參數,提取合約中的代幣。

AggregationRouterV 5

AggregationRouterV 5 合約存在swap 函數,其實現如下:

通過代碼識別DeFi中的套利機會

校驗了desc 中的minReturnAmount 後,從desc 中獲取srcToken 和dstToken,接下來986-997 行可以通過構造desc 結構體中的flags 和srcToken 進行繞過:

通過代碼識別DeFi中的套利機會

然後執行函數_execute, 這裡會進行call 調用,並會校驗執行狀態,由於executor 由用戶傳入,因此這裡我們可以使用 0 地址進行繞過:

通過代碼識別DeFi中的套利機會

然後獲取合約中dstToken 的餘額。 1007-1018 行我們可以構造desc 中flags 以及minReturnAmount 進行繞過:

通過代碼識別DeFi中的套利機會

最後會將合約中的dstToken 餘額都轉到dstReceiver 地址中,該地址也由用戶控制:

通過代碼識別DeFi中的套利機會

通過以上的步驟,我們能構造傳入swap 函數的參數從而將AggregationRouterV 5 合約中的代幣提走。

AggregationRouterV 4

AggregationRouterV 4 與AggregationRouterV 5 差別不大,AggregationRouterV 4 中也存在swap 函數,實現如下:

通過代碼識別DeFi中的套利機會

可以發現跟AggregationRouterV 5 的swap 函數的實現是一樣的,只是AggregationRouterV 5 對call 進行了優化,因此使用和AggregationRouterV 5 一樣的方法即可提取出存在AggregationRouterV 4 合約中的代幣。

總結

本文簡單介紹了部分去中心化交易所以及聚合器,並探討了其中可能存在的套利,從合約代碼層面分析了套利的原理,但在實際中能否成功還和諸多因素相關,如GAS,節點速度等。

參考 Reference

  • 如何從defi 中撿錢

  • What Is Uniswap

  • SUshi Academy

  • About DODO

  • 1inch aggregation protocol

關於我們

At Eocene Research, we provide the insights of intentions and security behind everything you know or don’t know of blockchain, and empower every individual and organization to answer complex questions we hadn’t even dreamed of back then.

了解更多: Website | Medium | Twitter

來源:星球日報

Total
0
Shares
Related Posts