
智能合約愛好者, 您的 Solidity 編譯器可能已悄悄刪除了您需要的儲存操作,而您在原始碼中永遠不會發現。 Solidity 0.8.38 於上週四發布。 它修復了從 0.8.19 到 0.8.37 每個版本中都存在的 Yul 優化器錯誤。 優化器會記錄記憶體和儲存中的內容, 並利用這些記錄,以已知的值取代載入操作,或跳過寫入相同資料的儲存操作。 為判斷兩個位址是否可能重疊,它將每個位址描述為基礎變數加上偏移量。 相同基礎、不同偏移,因此必須是不同插槽。 這些描述會被快取。 然後有人重新指派了基礎變數, 但優化器並非總能察覺。 現在,它會將一個基於舊值構建的位址,與一個基於新值構建的位址進行比較,並假設它們共享同一基礎。 它判斷它們不同,但在執行時它們指向同一位置。 結果是過時的記錄。 後續的載入操作可能返回舊值, 您需要的儲存操作可能被移除, 對該位置進行 keccak256 運算可能雜湊過時的資料。 僅當啟用優化器編譯的程式碼才會受影響。 使用 via-IR 時,任何程式碼都可能觸發此問題,即使沒有內聯組合語言。 使用預設的傳統流程時,僅部分內聯組合語言和編譯器生成的輔助函式會受影響。 未優化的建置是安全的。 團隊將此問題評為低嚴重性,並做了我期望每個編譯器團隊都做的事: 他們使用修復前後的版本,重新編譯了 Sourcify 資料庫中所有已驗證的合約,結果所有位元組碼均完全相同。 因此,此問題極為罕見。 但「罕見」不等於「從未發生」,尤其是當您代碼是新寫的且尚未部署時。 此錯誤最初由以太坊基金會的漏洞懸賞計畫發現,第二份報告顯示,即使沒有使用組合語言的純 Solidity 代碼也可能觸發此問題。
