By : yudan@慢霧安全團隊
背景
2021 年1 月27 日,據慢霧區情報,SushiSwap 再次遭遇攻擊,此次問題為DIGG-WBTC 交易對的手續費被攻擊者通過特殊的手段薅走。慢霧安全團隊在收到情報後立馬介入相關事件的分析工作,以下為攻擊相關細節。
SushiMaker 是什麼
SushiMaker 是SushiSwap 協議中的一個重要的組件,其用於收集SushiSwap 每個交易對的手續費,並通過設置每個代幣的路由,將不同交易對的手續費最終轉換成sushi 代幣,回饋給sushi 代幣的持有者。這個過程就是發生在SushiMaker 合約上。
說說恆定乘積
恆定乘積的公式很簡單,在不計算手續費的情況下,恆定乘積的公式為
也就是說每次兌換,其實都是遵循這個公式,及交易前後K 值不變,在兌換的過程中,由於要保持K 值不變,公式的形式會是這個樣子
其中X 代表賣掉的代幣,Y 代表要購買的代幣,那麼每次能兌換到的代幣數量會是這個樣子(具體的推導過程就不演示了:D)
從公式上可以看到,當輸出代幣Y 的兌換數量上限取決於Y 代幣的數量,而和X 代幣數量的大小無關,反過來說,如果要賣掉的X 代幣數量很大,但是Y 代幣的數量很小,那麼就會造成大量的X 代幣只能兌換出少量的Y 代幣,而這個兌換價格相比正常的交易價格會偏離很多,這就是所謂的滑點,是本次攻擊中的關鍵。
攻擊流程
2020 年11 月30 日,SushiSwap 就曾因為SushiMaker 的問題出現過一次攻擊(詳解參閱:以小博大,簡析Sushi Swap 攻擊事件始末),本次攻擊和第一次攻擊相似,但流程上有區別。相較於舊合約,在新的合約中, 手續費在兌換的過程中會通過bridgeFor 函數為不同交易對中的代幣尋找特定的兌換路由,然後進行兌換。
其中,bridgeFor 函數的邏輯如下:
根據bridgeFor 的邏輯,我們不難發現,如果沒有手動設置過特定幣種的bridge,那麼默認的bridge 是WETH,也就是說,在未設置bridge 的情況下,默認是將手續費兌換成WETH。而DIGG 這個幣,就是正好沒有通過setBridge 設置對應的bridge 的。
但是這裡還有一個問題,就是在swap 的過程中,如果這個交易對不存在,兌換的過程是失敗的。本次攻擊中,DIGG-WETH 這個交易對一開始並不存在,所以攻擊者預先創建一個DIGG-WETH 的交易對,然後添加少量的流動性。這個時候如果發生手續費兌換,根據前面說的恆定乘積的特性,由於DIGG-WETH 的流動性很少,也就是DIGG-WETH 中的WETH 上限很小,而SushiMaker 中的要轉換的手續費數量相對較大,這樣的兌換會導致巨大的滑點。兌換的過程會拉高DIGG-WETH 交易對中WETH 兌DIGG 的價格,並且,DIGG-WETH 的所有DIGG 手續費收益都到了DIGG-WETH 交易中。通過觀察DIGG-WETH 交易對的流動性情況,流動性最大的時候也才只有不到2800 美元的流動性,這個結果也能和公式的推導相互驗證。
攻擊者在SushiMaker 完成手續費轉換後,由於DIGG-WETH 交易對中WETH 兌DIGG 的價格已經被拉高,導致少量的WETH 即可兌換大量的DIGG,而這個DIGG 的數量,正是DIGG-WBTC 交易對的大部分手續費收入。
總結
本次攻擊和SushiSwap 第一次攻擊類似,都是通過操控交易對的兌換價格來產生獲利。但是過程是不一樣的。第一次攻擊是因為攻擊者使用LP 代幣本身和其他代幣創建了一個新的交易對,並通過操縱初始流動性操控了這個新的交易對的價格來進行獲利,而這次的攻擊則利用了DIGG 本身沒有對WETH 交易對,而攻擊者創建了這個交易對並操控了初始的交易價格,導致手續費兌換過程中產生了巨大的滑點,攻擊者只需使用少量的DIGG 和WETH提供初始流動性即可獲取巨額利潤。
相關參考鏈接如下:
SushiMaker 歸集手續費交易:
https://etherscan.io/tx/0x90fb0c9976361f537330a5617a404045ffb3fef5972cf67b531386014eeae7a9
攻擊者套利交易:
https://etherscan.io/tx/0x0af5a6d2d8b49f68dcfd4599a0e767450e76e08a5aeba9b3d534a604d308e60b
DIGG-WETH 流動性詳情:
https://www.sushiswap.fi/pair/0xf41e354eb138b328d56957b36b7f814826708724
Sushi 第一次被攻擊詳解:
https://mp.weixin.qq.com/s/-Vp9bPSqxE0yw2hk_yogFw