From d75e4f4c75d4a6a62afda1dd7864a8f0c1c14c49 Mon Sep 17 00:00:00 2001 From: lgalende Date: Thu, 2 Jul 2026 00:29:55 -0300 Subject: [PATCH] evm: fix smart accounts handler --- .../smart-accounts/SmartAccountsHandler.sol | 16 ++++++---------- .../test/smart-accounts/FallbackMock.sol | 9 +++++++++ .../smart-accounts/SmartAccountsHandler.test.ts | 6 ++++++ 3 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 packages/evm/contracts/test/smart-accounts/FallbackMock.sol diff --git a/packages/evm/contracts/smart-accounts/SmartAccountsHandler.sol b/packages/evm/contracts/smart-accounts/SmartAccountsHandler.sol index b482da3..fb67d62 100644 --- a/packages/evm/contracts/smart-accounts/SmartAccountsHandler.sol +++ b/packages/evm/contracts/smart-accounts/SmartAccountsHandler.sol @@ -16,6 +16,7 @@ pragma solidity ^0.8.20; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/utils/Address.sol'; +import '@openzeppelin/contracts/utils/introspection/ERC165Checker.sol'; import '../interfaces/ISafe.sol'; import '../interfaces/ISmartAccount.sol'; @@ -23,6 +24,8 @@ import '../interfaces/ISmartAccountsHandler.sol'; import '../utils/Denominations.sol'; contract SmartAccountsHandler is ISmartAccountsHandler { + using ERC165Checker for address; + /** * @dev Tells whether an account is a supported smart account * @param account Address of the account being queried @@ -90,11 +93,7 @@ contract SmartAccountsHandler is ISmartAccountsHandler { * @param account Address of the account being queried */ function _isMimicSmartAccount(address account) internal view returns (bool) { - try ISmartAccount(account).supportsInterface(type(ISmartAccount).interfaceId) returns (bool ok) { - return ok; - } catch { - return false; - } + return account.supportsInterface(type(ISmartAccount).interfaceId); } /** @@ -102,10 +101,7 @@ contract SmartAccountsHandler is ISmartAccountsHandler { * @param account Address of the account being queried */ function _isSafe(address account) internal view returns (bool) { - try ISafe(account).getThreshold() returns (uint256) { - return true; - } catch { - return false; - } + (bool success, bytes memory data) = account.staticcall(abi.encodeWithSelector(ISafe.getThreshold.selector)); + return success && data.length == 32; } } diff --git a/packages/evm/contracts/test/smart-accounts/FallbackMock.sol b/packages/evm/contracts/test/smart-accounts/FallbackMock.sol new file mode 100644 index 0000000..1b998b4 --- /dev/null +++ b/packages/evm/contracts/test/smart-accounts/FallbackMock.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.20; + +contract FallbackMock { + fallback() external payable {} + + receive() external payable {} +} diff --git a/packages/evm/test/smart-accounts/SmartAccountsHandler.test.ts b/packages/evm/test/smart-accounts/SmartAccountsHandler.test.ts index 382be61..31fb7ec 100644 --- a/packages/evm/test/smart-accounts/SmartAccountsHandler.test.ts +++ b/packages/evm/test/smart-accounts/SmartAccountsHandler.test.ts @@ -45,6 +45,12 @@ describe('SmartAccountsHandler', () => { expect(await handler.isSmartAccount(handler)).to.be.false }) + it('returns false for contracts with a fallback only', async () => { + const fallback = await ethers.deployContract('FallbackMock') + + expect(await handler.isSmartAccount(fallback)).to.be.false + }) + it('returns true for a Mimic SmartAccount', async () => { expect(await handler.isSmartAccount(smartAccountContract)).to.be.true })