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