DeFiTuna借貸池被黑約57萬美元:一個「空池子」如何騙過清算檢查
取整歸零的漏洞
7月16日,Solana上的借貸協議DeFiTuna被 exploit,損失約56.96萬枚USDC。安全公司CertiK把整條攻擊鏈拆得很清楚:攻擊者沒有硬撬合約,而是造了一個幾乎空的TUNA/USDC池子,把它變成借款流出後的「目的地」,再利用協議估值時的一個取整漏洞,讓系統誤以為這筆倉位「健康」,從而堂而皇之地把借出來的錢提走。

事情從一筆凌晨的交易開始。7月16日05:48左右,攻擊者先建了一個幾乎沒有任何流動性的TUNA/USDC Fusion池,初始價格故意設得接近官方預言機價格,於是DeFiTuna上線前的「價格偏離檢查」順利過關。接著,他們在池子裡掛了兩個自己控制、價格刻在異常高位(tick 208,640)的限價單,合計只放了約0.001枚TUNA。
真正的殺招在估值函式里。 攻擊者呼叫DeFiTuna的開放倉位指令,從借貸池借出約57萬USDC,經由內嵌的Jupiter路由,把這筆錢 swap 進那個精心準備的薄池子,換回的TUNA少到可以忽略——精確算下來只有約0.000494枚。詭異的地方來了:DeFiTuna在 is_healthy() 裡給倉位估值時,先按預言機價格算出約0.9077的數值,再用 to_num() 把正數定點值轉成整數、直接丟棄小數部分,結果變成0。

因為「空倉位槓桿永遠是1.0倍」這個隱含假設,總價值為0的倉位被系統判定為健康。 清算檢查就這樣被繞了過去。隨後,那筆USDC在經濟上已經屬於兩個惡意限價單,攻擊者各自呼叫 DecreaseLimitOrder,分別提走約28.4萬USDC。整個過程的脆弱點,就藏在 compute_total_and_debt() 第53行那個「向下取整」裡。
資金很快被分散到多個跳轉錢包,最後歸集到兩個主地址,分別持有約38.3萬和18.4萬美元,再經由Mayan跨鏈橋從Solana轉到以太坊。在以太坊上,140枚ETH被存進隱私工具Railgun,另有約30萬枚DAI留在錢包裡。

這類漏洞的可怕之處在於,它不靠「偷私鑰」,而是利用協議自己寫的數學假設。當一處四捨五入能把資產總值歸零,再聰明的預言機也救不了清算邏輯。 對做借貸、做機槍池的團隊來說,任何「先乘後取整」「空倉預設健康」的寫法,都該在審計時當作頭等風險來拆——DeFiTuna這57萬美元,買的就是一個教訓。