NFT項目Akutars 項目拍賣合約由於多個代碼缺陷導致11,539.5 枚ETH 永久無法取出。慢霧安全團隊進行分析了合約後發現:
1. Akutars 拍賣合約中存在bid 與processRefunds 功能,用戶分別可以進行拍賣出價與退款操作。
2. 在拍賣結束後發起processRefunds 退款操作時拍賣合約將遍歷出價用戶,並通過低級調用call 為用戶進行退款,但並未限制這一調用的gasLimit。而未做此gasLimit 限制的情況下,拍賣合約將使用發起者的全部gas 進行外部調用。
3. 但由於Akutars 拍賣合約並不限制合約參與拍賣,因此“惡意用戶”可以使用合約參與拍賣,並在其合約的接收以太函數中寫入惡意消耗gas 的邏輯,使得在進行退款流程時觸發此用戶合約,進而惡意消耗了調用發起者的全部gas,直接導致後續退款無法正常進行。
4. 幸運的是此“惡意用戶”僅僅只是做了風險驗證測試,最終解除了惡意消耗gas 的邏輯使得退款可以繼續順利進行。當然用戶也可以在拍賣結束的3 天后進行緊急退款。
5. 在用戶退款完成後項目方可以通過claimProjectFunds 功能提取合約中的拍賣所得。但拍賣合約在用戶進行bid 時使用totalBids 與bidIndex 記錄用戶所拍的數量與出價次數,而用戶是可以在一次出價中任意選擇所拍的數量的,因此在拍賣結束totalBids 實際上大於bidIndex。當前totalBids 為5495,bidIndex 僅為3669。
6. 但在claimProjectFunds 函數中卻要求refundProgress 退款數必須大於等於totalBids,項目方本意應是為了保證全部用戶完成退款後才可進行取款。而實際上refundProgress 是根據出價人總數進行計算的,也就是全部退款完成refundProgress 也只是會等於bidIndex。這就出現了refundProgress 永遠不會大於totalBids 的情況。最終導致合約中11,539.5 枚ETH 永遠無法取出。
綜上,即使在用戶無法退款問題被解決的情況下,由於出價人數與拍賣數量的計數不一致以及項目方取款函數的缺陷,最終都會導致Akutars 資金被永久鎖住的結果。