|
21 | 21 | from pydantic_core import core_schema |
22 | 22 | from typing_extensions import Annotated |
23 | 23 | from web3 import HTTPProvider, Web3 |
24 | | -from web3.exceptions import BadFunctionCallOutput |
| 24 | +from web3.exceptions import BadFunctionCallOutput, ContractLogicError |
25 | 25 |
|
26 | 26 | from .parsed import ABNFParsedMessage, RegExpParsedMessage |
27 | 27 |
|
@@ -327,7 +327,7 @@ def verify( |
327 | 327 |
|
328 | 328 | try: |
329 | 329 | address = w3.eth.account.recover_message(message, signature=signature) |
330 | | - except ValueError: |
| 330 | + except (ValueError, IndexError): |
331 | 331 | address = None |
332 | 332 | except eth_utils.exceptions.ValidationError: |
333 | 333 | raise InvalidSignature from None |
@@ -355,7 +355,11 @@ def check_contract_wallet_signature( |
355 | 355 | contract = w3.eth.contract(address=address, abi=EIP1271_CONTRACT_ABI) |
356 | 356 | hash_ = _hash_eip191_message(message) |
357 | 357 | try: |
358 | | - response = contract.caller.isValidSignature(hash_, bytes.fromhex(signature[2:])) |
| 358 | + # For message hashes stored on-chain for Safe wallets, the signatures |
| 359 | + # are always "0x" and should be passed in as-is. |
| 360 | + response = contract.caller.isValidSignature( |
| 361 | + hash_, signature if signature == "0x" else bytes.fromhex(signature[2:]) |
| 362 | + ) |
359 | 363 | return response.hex() == EIP1271_MAGICVALUE |
360 | | - except BadFunctionCallOutput: |
| 364 | + except (BadFunctionCallOutput, ContractLogicError): |
361 | 365 | return False |
0 commit comments