僅供教育參考,不構成投資建議;投資可能產生損失。
直接答案
當所有者呼叫 approve(spender, newAmount),將一個非零授權額度替換為另一個非零額度時,可能出現 ERC-20 授權競態。支出方可以看到待處理的變更,先透過 transferFrom 用掉舊額度,再在替換授權確認後使用新額度。
因此,ERC-20 規範建議用戶端介面先將同一支出方的授權額度設為 0,再設定新值。每筆交易都必須依序等待確認。如果代幣支援原子化的 increaseAllowance 或 decreaseAllowance 呼叫,就可以避免直接替換非零授權額度。
完成核查不代表資產、交易或系統已經安全。
運作方式
ERC-20 將 approve 定義為覆寫操作:成功呼叫 approve(spender, amount) 會把支出方的授權額度設為 amount。另一方面,transferFrom(owner, recipient, amount) 允許該支出方轉移所有者的代幣,並且通常會減少剩餘授權額度。待處理交易不會預留執行順序,因此支出方可以提交一筆在所有者變更授權前執行的轉帳。
有風險的轉換是 N -> M,其中 N > 0 且 M > 0。如果支出方在替換授權執行前用掉 N,之後的授權會重新設定額度 M。因此,在所有者的代幣餘額和代幣實作允許的範圍內,這一過程中最多可能支出 N + M。
範例
Alice 已授權某個協議支出 100 枚代幣。她提交 approve(protocol, 50),打算把剩餘授權額度降至 50。在這筆交易確認前,協議的支出方提交 transferFrom(Alice, recipient, 100),並讓它先執行。隨後,Alice 的授權把額度設為 50,支出方可以在另一筆轉帳中繼續使用。兩筆轉帳合計 150 枚代幣。
更安全的替換流程是先提交 approve(protocol, 0),等待確認並檢查更新後的授權額度和餘額,然後僅在新授權仍然合適時提交 approve(protocol, 50)。如果支出方在歸零交易確認前使用舊額度,Alice 就能看到餘額變化,並在授予新的 50 額度前停止操作。
風險
- 將授權額度設為
0無法撤銷已經執行的支出,也無法阻止支出方在歸零交易確認前使用舊額度。 - 如果不等待第一筆交易確認,就同時傳送歸零授權和替換授權,執行順序風險會再次出現。
increaseAllowance和decreaseAllowance不屬於基礎 ERC-20 標準;只有在經驗證的代幣合約支援它們時才應使用。- 只要無限授權仍然有效,所有者的全部代幣餘額都可能面臨風險。簽名前請核對鏈、代幣合約、支出方和金額。
- 有些代幣採用非標準的授權行為。請查看錢包模擬結果和交易 calldata,並在每一步之後確認鏈上授權額度。
常見誤解
- 「最新的授權交易會立即替換舊授權。」只有當交易在鏈上執行時,狀態才會改變。
- 「降低授權額度會把未來的總支出限制在新額度內。」支出方可能在變更執行前使用舊額度。
- 「先歸零可以保證不再有代幣轉出。」在歸零交易確認前,舊額度仍然可以使用。
- 「每種 ERC-20 都有
increaseAllowance和decreaseAllowance。」它們是選用擴充功能,並非 ERC-20 的要求。 - 「中斷網站連線就會撤銷代幣授權。」錢包連線狀態與代幣合約的鏈上授權額度是兩回事。
相關主題
來源
- ERC-20: Token Standard - Ethereum Improvement Proposals (查閱日期: 2026-08-20)
- ERC20 | OpenZeppelin Docs - OpenZeppelin (查閱日期: 2026-08-20)