Skip to content

Commit

Permalink
test: initial draft of sma-specific tests, move helper to test base
Browse files Browse the repository at this point in the history
  • Loading branch information
Zer0dot committed Aug 22, 2024
1 parent a1510cd commit 9b0b6b1
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 4 deletions.
4 changes: 0 additions & 4 deletions test/account/DirectCallsFromModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,4 @@ contract DirectCallsFromModuleTest is AccountTestBase {
emit ValidationUninstalled(module, entityId, true);
account1.uninstallValidation(_moduleEntity, "", new bytes[](1));
}

function _buildDirectCallDisallowedError(bytes4 selector) internal pure returns (bytes memory) {
return abi.encodeWithSelector(UpgradeableModularAccount.ValidationFunctionMissing.selector, selector);
}
}
106 changes: 106 additions & 0 deletions test/account/SemiModularAccount.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import {AccountTestBase} from "../utils/AccountTestBase.sol";
import {TEST_DEFAULT_VALIDATION_ENTITY_ID} from "../utils/TestConstants.sol";

Check failure on line 5 in test/account/SemiModularAccount.t.sol

View workflow job for this annotation

GitHub Actions / Run Linters

imported name TEST_DEFAULT_VALIDATION_ENTITY_ID is not used
import {SemiModularAccount} from "src/account/SemiModularAccount.sol";
import {ValidationConfig} from "src/helpers/ValidationConfigLib.sol";

import {console} from "forge-std/Test.sol";

Check failure on line 9 in test/account/SemiModularAccount.t.sol

View workflow job for this annotation

GitHub Actions / Run Linters

imported name console is not used
import {LibClone} from "solady/utils/LibClone.sol";

contract SemiModularAccountTest is AccountTestBase {
SemiModularAccount internal _sma;

address internal _other;

function setUp() public {
// This is separate from the equivalence testing framework (with the env boolean variable "SMA_TEST") with
// the goal of testing specific SMA functionality, rather than equivalence. This is also why we deploy a
// new account.
SemiModularAccount impl = new SemiModularAccount(entryPoint);

_other = address(0x4546b);

bytes32 salt = bytes32(0);
bytes memory immutables = abi.encodePacked(address(owner1));
(bool alreadyDeployed, address instance) =
LibClone.createDeterministicERC1967(address(impl), immutables, salt);

assertFalse(alreadyDeployed);

_sma = SemiModularAccount(payable(instance));
}

/* -------------------------------------------------------------------------- */
/* Negatives */
/* -------------------------------------------------------------------------- */

function test_Fail_InitializeDisabled() external {
ValidationConfig config;
bytes4[] memory selectors;
bytes memory installData;
bytes[] memory hooks;

vm.expectRevert(SemiModularAccount.InitializerDisabled.selector);
_sma.initializeWithValidation(config, selectors, installData, hooks);
}

function test_Fail_AccessControl_Functions() external {
vm.expectRevert(_buildDirectCallDisallowedError(SemiModularAccount.setFallbackSignerDisabled.selector));
_sma.setFallbackSignerDisabled(true);

vm.expectRevert(_buildDirectCallDisallowedError(SemiModularAccount.updateFallbackSigner.selector));
_sma.updateFallbackSigner(address(0));
}

function test_Fail_ExecuteWithAuthorization_DisabledFallbackSigner() external {
vm.prank(address(entryPoint));
_sma.setFallbackSignerDisabled(true);

vm.expectRevert(SemiModularAccount.FallbackSignerDisabled.selector);
vm.prank(owner1);
_executeWithFallbackSigner();
}

function test_Fail_ExecuteWithAuthorization_BytecodeOverriden() external {
vm.prank(address(entryPoint));
_sma.updateFallbackSigner(_other);

vm.expectRevert(SemiModularAccount.FallbackSignerMismatch.selector);
vm.prank(owner1);
_executeWithFallbackSigner();
}

/* -------------------------------------------------------------------------- */
/* Positives */
/* -------------------------------------------------------------------------- */

function test_Pass_GetFallbackSigner_Bytecode() external {
assertEq(_sma.getFallbackSigner(), owner1);
}

function test_Pass_GetFallbackSigner_Storage() external {
vm.prank(address(entryPoint));
_sma.updateFallbackSigner(_other);

assertEq(_sma.getFallbackSigner(), _other);
}

function test_Pass_ExecuteWithAuthorization_FallbackSigner() external {
vm.prank(owner1);
_executeWithFallbackSigner();
}

/* -------------------------------------------------------------------------- */
/* Internals */
/* -------------------------------------------------------------------------- */

function _executeWithFallbackSigner() internal {
// _signerValidation is already the ModuleEntity for fallback validation
_sma.executeWithAuthorization(
abi.encodeCall(account1.execute, (address(owner1), 0, "")),
_encodeSignature(_signerValidation, GLOBAL_VALIDATION, "")
);
}
}
4 changes: 4 additions & 0 deletions test/utils/AccountTestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,8 @@ abstract contract AccountTestBase is OptimizedTest {
{
return abi.encodePacked(uint32(validationData.length + 1), index, validationData);
}

function _buildDirectCallDisallowedError(bytes4 selector) internal pure returns (bytes memory) {
return abi.encodeWithSelector(UpgradeableModularAccount.ValidationFunctionMissing.selector, selector);
}
}

0 comments on commit 9b0b6b1

Please sign in to comment.