165 lines
5.7 KiB
Solidity
165 lines
5.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import {Test} from "forge-std/Test.sol";
|
|
import {AccountWalletRegistryExtended} from "../../contracts/smart-accounts/AccountWalletRegistryExtended.sol";
|
|
import {IAccountWalletRegistry} from "../../contracts/emoney/interfaces/IAccountWalletRegistry.sol";
|
|
|
|
/**
|
|
* @title AccountWalletRegistryExtendedTest
|
|
* @notice Tests for AccountWalletRegistryExtended with Smart Account support
|
|
*/
|
|
contract AccountWalletRegistryExtendedTest is Test {
|
|
AccountWalletRegistryExtended public registry;
|
|
address public admin;
|
|
address public accountManager;
|
|
address public smartAccountFactory;
|
|
address public entryPoint;
|
|
|
|
// Mock smart account (contract address)
|
|
address public mockSmartAccount;
|
|
|
|
bytes32 public accountRefId1 = keccak256("account1");
|
|
bytes32 public providerSmart = keccak256("METAMASK_SMART_ACCOUNT");
|
|
bytes32 public providerEOA = keccak256("METAMASK");
|
|
|
|
function setUp() public {
|
|
admin = address(0x1);
|
|
accountManager = address(0x2);
|
|
smartAccountFactory = address(0x3);
|
|
entryPoint = address(0x4);
|
|
|
|
// Deploy mock smart account (contract)
|
|
mockSmartAccount = address(new MockSmartAccount());
|
|
|
|
registry = new AccountWalletRegistryExtended(
|
|
admin,
|
|
smartAccountFactory,
|
|
entryPoint
|
|
);
|
|
|
|
vm.startPrank(admin);
|
|
registry.grantRole(registry.ACCOUNT_MANAGER_ROLE(), accountManager);
|
|
registry.grantRole(registry.ACCOUNT_MANAGER_ROLE(), address(registry)); // Self-call from linkSmartAccount->linkAccountToWallet
|
|
vm.stopPrank();
|
|
}
|
|
|
|
function test_linkSmartAccount() public {
|
|
vm.prank(accountManager);
|
|
registry.linkSmartAccount(accountRefId1, mockSmartAccount, providerSmart);
|
|
|
|
bytes32 walletRefId = keccak256(abi.encodePacked(mockSmartAccount));
|
|
assertTrue(registry.isLinked(accountRefId1, walletRefId));
|
|
assertTrue(registry.isActive(accountRefId1, walletRefId));
|
|
assertTrue(registry.isSmartAccount(walletRefId));
|
|
assertTrue(registry.isSmartAccountAddress(mockSmartAccount));
|
|
}
|
|
|
|
function test_linkSmartAccount_revertsIfNotContract() public {
|
|
address eoa = address(0x100);
|
|
|
|
vm.prank(accountManager);
|
|
vm.expectRevert("AccountWalletRegistryExtended: not a contract");
|
|
registry.linkSmartAccount(accountRefId1, eoa, providerSmart);
|
|
}
|
|
|
|
function test_linkSmartAccount_revertsIfZeroAddress() public {
|
|
vm.prank(accountManager);
|
|
vm.expectRevert("AccountWalletRegistryExtended: zero smartAccount");
|
|
registry.linkSmartAccount(accountRefId1, address(0), providerSmart);
|
|
}
|
|
|
|
function test_isSmartAccount() public {
|
|
bytes32 walletRefId = keccak256(abi.encodePacked(mockSmartAccount));
|
|
|
|
// Initially false
|
|
assertFalse(registry.isSmartAccount(walletRefId));
|
|
|
|
// Link smart account
|
|
vm.prank(accountManager);
|
|
registry.linkSmartAccount(accountRefId1, mockSmartAccount, providerSmart);
|
|
|
|
// Now true
|
|
assertTrue(registry.isSmartAccount(walletRefId));
|
|
}
|
|
|
|
function test_isSmartAccountAddress() public {
|
|
// Initially false
|
|
assertFalse(registry.isSmartAccountAddress(mockSmartAccount));
|
|
|
|
// Link smart account
|
|
vm.prank(accountManager);
|
|
registry.linkSmartAccount(accountRefId1, mockSmartAccount, providerSmart);
|
|
|
|
// Now true
|
|
assertTrue(registry.isSmartAccountAddress(mockSmartAccount));
|
|
}
|
|
|
|
function test_setSmartAccountFactory() public {
|
|
address newFactory = address(0x5);
|
|
|
|
vm.prank(admin);
|
|
registry.setSmartAccountFactory(newFactory);
|
|
|
|
assertEq(registry.smartAccountFactory(), newFactory);
|
|
}
|
|
|
|
function test_setSmartAccountFactory_revertsIfNotAdmin() public {
|
|
address newFactory = address(0x5);
|
|
|
|
vm.prank(accountManager);
|
|
vm.expectRevert();
|
|
registry.setSmartAccountFactory(newFactory);
|
|
}
|
|
|
|
function test_setEntryPoint() public {
|
|
address newEntryPoint = address(0x6);
|
|
|
|
vm.prank(admin);
|
|
registry.setEntryPoint(newEntryPoint);
|
|
|
|
assertEq(registry.entryPoint(), newEntryPoint);
|
|
}
|
|
|
|
function test_setEntryPoint_revertsIfNotAdmin() public {
|
|
address newEntryPoint = address(0x6);
|
|
|
|
vm.prank(accountManager);
|
|
vm.expectRevert();
|
|
registry.setEntryPoint(newEntryPoint);
|
|
}
|
|
|
|
function test_supportsBothEOAAndSmartAccount() public {
|
|
address eoa = address(0x100);
|
|
bytes32 eoaWalletRefId = keccak256(abi.encodePacked(eoa));
|
|
|
|
// Link EOA (using parent function)
|
|
vm.prank(accountManager);
|
|
registry.linkAccountToWallet(accountRefId1, eoaWalletRefId, providerEOA);
|
|
|
|
// Link Smart Account
|
|
vm.prank(accountManager);
|
|
registry.linkSmartAccount(accountRefId1, mockSmartAccount, providerSmart);
|
|
|
|
// Both should be linked
|
|
assertTrue(registry.isLinked(accountRefId1, eoaWalletRefId));
|
|
assertTrue(registry.isLinked(accountRefId1, keccak256(abi.encodePacked(mockSmartAccount))));
|
|
|
|
// Only smart account should be marked as smart account
|
|
assertFalse(registry.isSmartAccount(eoaWalletRefId));
|
|
assertTrue(registry.isSmartAccount(keccak256(abi.encodePacked(mockSmartAccount))));
|
|
}
|
|
|
|
// Events
|
|
event SmartAccountLinked(
|
|
bytes32 indexed accountRefId,
|
|
address indexed smartAccount,
|
|
bytes32 provider
|
|
);
|
|
}
|
|
|
|
// Mock Smart Account contract for testing
|
|
contract MockSmartAccount {
|
|
// Empty contract to simulate smart account
|
|
}
|