一個長期在以太坊上獵取普通交易者的 MEV 機器人,最終也掉進了一個價值 750 萬美元的「客製版」陷阱。
6 月 21 日,以太坊上知名的三明治套利機器人 Jaredfromsubway.eth 遭到攻擊,地址內的 WETH、USDC 等資產被轉走,初步統計損失超過 750 萬美元(不過目前公開披露的損失口徑仍有差異)。
有意思的是,這次攻擊既不是私鑰外洩,也沒有利用傳統意義上的智慧合約漏洞,而是攻擊者提前部署大量虛假代幣、流動性池和輔助合約,將其包裝成可能存在套利空間的交易路徑,誘導機器人在自動化執行過程中,向惡意合約授予了 ERC-20 的 Approval,最終「合法」轉走了該 MEV 機器人的資產。
截至發文時,Jaredfromsubway.eth 已透過鏈上訊息向攻擊者公開喊話,表示「若在 48 小時內歸還 2150 枚以太坊,願意支付五成白帽賞金,否則將採取一切可行的法律及執法手段追責」。
不過,連高度專業化、由程式碼驅動的 MEV 機器人,都會在 Approval 上栽跟頭,也不禁讓人重新審視,這個我們每天都在使用的「Approval」動作,究竟隱藏著多大的危險?
一、一場專為 MEV 機器人設計的反向圍獵
如果認真復盤這次攻擊事件,就會發現這並不是一次偶然觸發的漏洞,而是一場針對 Jaredfromsubway.eth 交易邏輯設計的長期圍獵。
Jaredfromsubway.eth 一直是以太坊上最知名的三明治套利機器人之一。所謂三明治攻擊,簡單來說,就是機器人發現一筆即將發生的鏈上交易後,搶先在使用者之前買入,推動價格上漲;等使用者以更差的價格完成交易,再立即賣出,從中賺取價差。
也正因如此,該策略要求機器人持續掃描鏈上交易,以極快速度判斷套利機會,並組織交易路徑,去調用不同的代幣和合約,這也意味著速度越快、覆蓋的資產與協議越多,機器人能夠捕捉的機會也就越多。
但正是這一點,成為了這次事件的突破口。
根據事後復盤,攻擊者並沒有直接攻擊機器人的資金合約,而是花費了數週時間,構造出一組看起來能夠盈利的交易環境:
- 第一步,是部署大量虛假代幣與流動性池。這些代幣在名稱、介面和交易行為上模仿 WETH、USDC、USDT 等常見資產,讓機器人的自動識別系統誤以為發現了正常交易路徑;
- 第二步,是逐步取得機器人的信任。在早期測試中,機器人授予的授權會隨著交易正常使用,等到機器人的系統開始重複執行類似路徑後,攻擊者再調整合約邏輯,讓機器人產生的部分授權不再被實際消耗,也沒有在交易結束後歸零,導致這些授權就這樣留了下來;
- 最後,攻擊者集中調用仍然有效的授權額度,將機器人合約裡的真實 WETH、USDC 和 USDT 轉出;
說白了,整套攻擊完全瞄準了 MEV 機器人的運行特點,也就是先製造一個符合其盈利判斷規則的環境,再利用其追求自動執行交易路徑的機制,讓系統主動交出資產調用權。
這也解釋了為什麼連高度專業化的 MEV 機器人都會中招。
它懂得如何計算價差、Gas 成本和交易順序,卻未必會對每一個新出現的合約進行充分的身分驗證。從這個角度說,普通使用者的問題是「沒有看懂就點了確認」,自動化機器人的問題則是「沒有確認就自動執行」。
表面上看,兩者完全不同,底層風險卻很接近,因為它們都把授權當成完成交易前的一個普通步驟,而沒有清楚意識到它潛藏的風險有多高。
二、Approval 為什麼總是被低估?
眾所周知,在以太坊及 EVM 相容鏈的 ERC-20 標準中,Approve(授權)是一個相當底層的設計。
不過使用者在錢包裡直接轉帳時,通常調用的是 transfer,一般不涉及 Approve;只有在 DEX、借貸、質押或者添加流動性等智慧合約場景時,使用者需要讓智慧合約代表自己調用代幣,才會涉及 Approval。
舉個例子,當我們想在 Uniswap 上把 USDT 換成 ETH 時,Uniswap 的智慧合約是不能直接去你錢包裡拿走 USDT 的,必須先執行一次 Approve 去告訴系統「我允許 Uniswap 劃走我錢包裡的 X 個 USDT」。
只要授權完成後,獲得權限的合約才能透過 transferFrom,在限定額度內調用使用者的 USDT,後續的 Swap 也才能順利完成。
也就是說,Approval 本身並不是漏洞,而是 DeFi 能夠正常運作的重要基礎。只不過,問題在於它有點像支付寶/微信的自動扣款權限:
使用者沒有把帳戶密碼交給商戶,但卻允許商戶在約定範圍內主動扣款,只要授權仍然有效,後續扣款就不需要使用者再次輸入密碼或逐筆確認,這就天然帶來一些問題。
首先是無限授權的問題,大家往往把一次交易變成長期權限。主要是為了減少重複授權產生的操作和 Gas 成本,不少 DApp 會預設申請一個極大的授權額度,也就是常說的「無限授權」。
使用者原本可能只想用 100 USDC 完成一次交易,卻允許合約未來動用自己地址裡的全部 USDC。那只要該授權沒有被撤銷,即便使用者當時的錢包裡只有少量資產,未來重新轉入的 USDC 也可能持續受到影響。
其次就是授權預設不會隨著離開 DApp 而消失。很多使用者會把「斷開錢包連接」和「撤銷授權」混為一談,實際上,斷開連接只是讓網頁暫時無法讀取或請求目前錢包,並不會改變已經寫入區塊鏈的 Approval。
關閉網頁、刪除 DApp、清除瀏覽器快取,甚至更換錢包應用,都不會讓它自動失效。
最後,即便是正常合約,也可能在未來變得危險。因為很多授權風險並不只來自一開始就是惡意的釣魚網站,就像此次的圍獵,使用者可能向一個當時正常的協議授予權限,但此後協議合約遭到攻擊、管理員金鑰外洩、可升級邏輯被替換,或者其調用的路由合約出現問題。
對使用者而言,資產仍然留在自己的地址裡,但從權限角度看,另一個合約一直擁有調用這些資產的能力。因此,Approval 風險不只是「我有沒有授權給壞人」,還包括「我授權的對象以後會不會出問題」。
三、那該如何管控 Approval 風險
面對 Approval 風險,最簡單的建議就是「不要無限授權」。
但在真實的 DeFi 使用環境裡,完全拒絕授權並不現實,正如上文所述,授權本身並不是漏洞,它是鏈上應用調用資產的基礎方式。
真正需要改變的,是將 Approval 從一次性的確認動作,變成一套持續的權限管理機制。
那對普通使用者來說,首先需要建立幾個基本習慣:
- 第一,遵循「最小權限」原則。在錢包跳出授權提示時,盡量根據本次互動的實際需要設定額度,比如只準備使用 100 USDT,就盡可能只授權接近 100 USDT 的額度,而不是直接開放無限權限;
- 第二,區分儲存錢包和互動錢包。長期儲存大額資產的地址,盡量不要頻繁連接陌生 DApp;參與空投、Mint、新專案和高風險 DeFi 互動時,可以使用單獨的地址,將潛在損失限制在較小範圍內;
- 第三,定期檢查並撤銷不再需要的授權。使用者可以透過 Revoke.cash 等工具,或在 imToken 中進入對應代幣頁面,點擊左下角「Token Function」,再選擇「授權管理」,查看該地址的授權對象、代幣和額度,並對不再使用或來源不明的權限發起撤銷(延伸閱讀《手把手教你使用 Revoke.cash 進行授權管理》);
當然,說一千道一萬,面對防不勝防的授權攻擊,僅僅依靠使用者的安全意識和定期檢查還是不夠的,畢竟大多數使用者很難分辨一串合約地址究竟屬於誰,也很難判斷某個授權額度是否合理。
那作為使用者進入 Web3 的第一道護城河,錢包必須在產品能力上提供主動防禦。
以 imToken 為例,就會對已識別的風險代幣、地址和 DApp 進行標記或攔截;當使用者向普通外部帳戶授予代幣權限,或者向合約地址直接轉帳時,也會提供針對性的風險提示。這些提示無法取代使用者判斷,但至少可以在真正簽名之前,增加一道必要的安全緩衝。
除此之外,imToken 還在 DApp 登入、轉帳、代幣兌換與授權等關鍵環節,對簽名內容進行結構化解析與可讀化呈現,盡可能幫助使用者在確認之前理解自己正在同意什麼,確保使用者簽署的內容,必須與其所看到的行為保持一致,而不是被壓縮成一段難以辨識的雜湊資料。
隨著 ERC-7730 等 Clear Signing 標準進一步推進,這種「所見即所簽(What You See Is What You Sign)」的可讀化展示,也有望從單一錢包的產品能力,逐漸成為錢包、DApp 和智慧合約之間共享的產業標準。
總的來看,私鑰決定誰擁有帳戶,Approval 決定誰還能調用帳戶裡的資產,兩者並不是一回事,卻同樣重要。
這也意味著,錢包安全不能只停留在「私鑰有沒有外洩」,而且這需要從使用者到錢包,大家共同努力:對使用者來說,需要在授權前看清對象和額度,在互動結束後及時清理不再需要的權限;對錢包來說,則需要讓這些原本隱藏在合約裡的權限變得更可見、更容易理解,也更方便被限制和撤銷。
畢竟,真正危險的未必是剛剛發生的那筆轉帳,也可能是一個早已被遺忘、卻始終沒有失效的授權。