何が EOA 検査をバイパスするか?
多くの DeFi 契約は、重要な操作を EOA のみに許可しています。契約アドレスは呼び出せません。これは msg.sender をチェックすることで実現されています。しかし、攻撃者は自身の悪意のある契約で、EOS や delegatecall などの方法を使用して msg.sender を EOA アドレスに偽装することで、検査をバイパスすることができます。
EOA 検査をバイパスする方法:
msg.sender だけでなく、tx.origin もチェックして、呼び出し元が EOA であることを確認します。
ユーザーの最初の呼び出し時に EOA を記録するために状態変数を使用し、後続の呼び出しでは recordedEOA を強制的に使用します。
安全なインターフェース契約で EOA 検査を行い、ユーザーはそのインターフェース契約を介してのみ呼び出すことができます。
OpenZeppelin の EOAChecker などの監査済みの安全ライブラリを使用します。
コード例:
// Also check tx.origin
require(msg.sender == tx.origin, "Not EOA");
// Record EOA on first call
address public userEOA;
function initEOA() external {
require(userEOA == address(0), "Already initialized");
userEOA = msg.sender;
}
function criticalFunc() external {
require(msg.sender == userEOA, "Only EOA can call");
// Function logic
}