Common DeFi Invariants Every Protocol Must Respect
三句話摘要
智能合約審計中「不變量(Invariant)」的分類與應用技巧。 把「系統在各種操作前後應滿足的條件」明確定義成不變量,是發現智能合約深層漏洞最系統化的方法。 不變量難以憑直覺發現,但對測試極有價值。 開發者在撰寫業務邏輯時鮮少主動思考不變量,但它們是模糊測試(fuzzing)與形式化驗證的基礎輸入。
重點整理
重點- 1
不變量難以憑直覺發現,但對測試極有價值。 開發者在撰寫業務邏輯時鮮少主動思考不變量,但它們是模糊測試(fuzzing)與形式化驗證的基礎輸入。
- 2
償債能力(Solvency)是最重要的不變量之一。 核心問題是:當用戶數降為零時,系統能否停止並退還所有資金?現實中常見「最後一個用戶資產被鎖死」的漏洞正是違反了這一點。
- 3
回程不變量(Roundtrip)與對稱性不變量揭露舍入錯誤。 存入再燒毀應回到原狀態;以存入量或取出量兩種方式指定的 ERC-4626 操作應等價——若舍入方向不一致,狀態就會發生偏移。
- 4
組合不變量(Compositional Invariant)驗證多條路徑的終態一致性。 將一個代幣換成另一個,與「先加流動性再移除」,對資金池而言理論上應達到相同狀態,若不一致即代表存在漏洞。
實用技巧與重點
乾貨- 工具/技術:模糊測試(Fuzzing)、形式化驗證(Formal Verification)
- 協議類型:ERC-4626 Vault 協議、AMM 流動性池
- 不變量分類:
- Solvency(償債能力)
- Data Integrity(資料完整性):兩個相關聯變數必須同步修改
- Roundtrip Invariant:deposit → redeem 應回到原始狀態
- Symmetry Invariant:mint 與 deposit 指定不同方向應等價
- Shared Resource Invariant:共享變數不可被單一用戶耗盡
- Compositional Invariant:大操作 = 子操作之和,終態應一致
- 常見漏洞場景:
- 用戶數為零時最後一位用戶資產被鎖定
- 舍入方向錯誤導致狀態累積偏移
- 不同路徑(swap vs. add/remove liquidity)終態不一致
- 零用戶時仍可 mint 代幣或份額
結論
結論“把「系統在各種操作前後應滿足的條件」明確定義成不變量,是發現智能合約深層漏洞最系統化的方法。”
完整解析
詳細演講者 Anton 開門見山指出,無論面對多複雜的新協議,審計員或開發者最核心的工作是識別「不變量(Invariant)」——亦即系統在任何操作前後都應成立的條件。他坦言,開發者在撰寫業務邏輯時往往只思考用戶故事與產品需求,鮮少主動定義不變量;但正因如此,不變量的缺失才成為漏洞的溫床。即便不採用形式化驗證,不變量也是模糊測試的理想輸入素材。
Anton 首先強調「償債能力(Solvency)」是最基礎的不變量。對於任何鎖定用戶資金的協議——尤其是有 LP(流動性提供者)的系統——核心問題是:合約能否在任何時間點如數償還所有存款?他建議問三個問題:一、當用戶數降為零時,系統能否正常停止?現實中常見漏洞是「最後一個用戶的資產被協議永久鎖死」。二、系統是否在每次操作中都對自身獲利?此類設計若未約束,會系統性地侵蝕留在協議內用戶的份額。三、資料完整性——合約中是否存在應同步修改卻未加以約束的關聯變數?
接著他介紹幾類更具操作性的不變量。回程不變量(Roundtrip Invariant)適用於 ERC-4626 等 Vault 協議:先 deposit 再 redeem,應回到完全相同的狀態;若舍入方向不正確,每次操作都會累積微小誤差,長期下來可被攻擊者套利。對稱性不變量(Symmetry Invariant)則指出,以「存入量」或「取出量」兩種方式指定的操作在數學上應等價,但某些協議(如演講中提到的 Bouncer 協議)在不同指定方式下走的路由不同,導致結果出現偏差。
最後他介紹組合不變量(Compositional Invariant),這也是他認為最優雅的一類。核心思想是:一個大操作拆成多個小操作後,終態應與直接執行大操作相同。更進一步,不同的路徑若在邏輯上等價,其終態也應一致——例如,「用 Token A 換 Token B」與「先用 Token A 加入流動性、再移除並取出 Token B」,對資金池的影響理論上應相同。若不一致,代表協議存在套利漏洞或狀態損壞。他特別提醒,X 與 Y 的大小可以任意組合,因此這類不變量能有效覆蓋邊界條件。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

