什麼是繞過 EOA 檢查?
許多 DeFi 合約只允許 EOA 進行關鍵操作。合約地址不可調用。這是通過檢查 msg.sender 實現的。但攻擊者可以在自己的惡意合約中,使用 EOS 或 delegatecall 等方式偽造 msg.sender 為一個 EOA 地址,就可以繞過檢查。
防止繞過 EOA 檢查的方法:
不僅檢查 msg.sender,還檢查 tx.origin,以確保調用者為 EOA。
使用狀態變量在用戶首次調用時記錄 EOA,後續調用強制使用 recordedEOA。
在安全的介面合約中進行 EOA 檢查,用戶只能通過該介面合約調用。
使用 OpenZeppelin 的 EOAChecker 等審計過的安全庫。
代碼示例:
// 同時檢查tx.origin
require(msg.sender == tx.origin, "非EOA");
// 在第一次調用時記錄EOA
address public userEOA;
function initEOA() external {
require(userEOA == address(0), "已初始化");
userEOA = msg.sender;
}
function criticalFunc() external {
require(msg.sender == userEOA, "僅限EOA調用");
// 函數邏輯
}