Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix loop increment issue and add test #4

Merged
merged 1 commit into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/account/BaseModularAccountLoupe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ abstract contract BaseModularAccountLoupe is IPluginLoupe {
uint256 numHooks = preExecHooks.length;
execHooks = new ExecutionHooks[](numHooks);

for (uint256 i = 0; i < numHooks; i++) {
for (uint256 i = 0; i < numHooks;) {
execHooks[i].preExecHook = preExecHooks[i];
execHooks[i].postExecHook = _storage.selectorData[selector].associatedPostExecHooks[preExecHooks[i]];

Expand Down Expand Up @@ -88,7 +88,7 @@ abstract contract BaseModularAccountLoupe is IPluginLoupe {
uint256 numHooks = prePermittedCallHooks.length;
execHooks = new ExecutionHooks[](numHooks);

for (uint256 i = 0; i < numHooks; i++) {
for (uint256 i = 0; i < numHooks;) {
execHooks[i].preExecHook = prePermittedCallHooks[i];
execHooks[i].postExecHook =
_storage.permittedCalls[key].associatedPostPermittedCallHooks[prePermittedCallHooks[i]];
Expand Down
105 changes: 105 additions & 0 deletions test/account/ModularAccountLoupe.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.so
import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol";
import {ISingleOwnerPlugin} from "../../src/plugins/owner/ISingleOwnerPlugin.sol";
import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol";
import {
ManifestAssociatedFunctionType,
ManifestExecutionHook,
ManifestFunction,
PluginManifest
} from "../../src/interfaces/IPlugin.sol";
import {IPluginLoupe} from "../../src/interfaces/IPluginLoupe.sol";
import {IPluginManager} from "../../src/interfaces/IPluginManager.sol";
import {IStandardExecutor} from "../../src/interfaces/IStandardExecutor.sol";
import {FunctionReference, FunctionReferenceLib} from "../../src/libraries/FunctionReferenceLib.sol";

import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol";
import {ComprehensivePlugin} from "../mocks/plugins/ComprehensivePlugin.sol";
import {MockPlugin} from "../mocks/MockPlugin.sol";

contract ModularAccountLoupeTest is Test {
EntryPoint public entryPoint;
Expand Down Expand Up @@ -189,6 +196,104 @@ contract ModularAccountLoupeTest is Test {
);
}

function test_pluginLoupe_getHooks_multiple() public {
// Add a second set of execution hooks to the account, and validate that it can return all hooks applied
// over the function.

PluginManifest memory mockPluginManifest;

mockPluginManifest.executionHooks = new ManifestExecutionHook[](1);
mockPluginManifest.executionHooks[0] = ManifestExecutionHook({
executionSelector: ComprehensivePlugin.foo.selector,
preExecHook: ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
functionId: 0,
dependencyIndex: 0
}),
postExecHook: ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
functionId: 0,
dependencyIndex: 0
})
});

mockPluginManifest.permittedCallHooks = new ManifestExecutionHook[](2);
// Copy over the same hooks from executionHooks.
mockPluginManifest.permittedCallHooks[0] = mockPluginManifest.executionHooks[0];
mockPluginManifest.permittedCallHooks[1] = ManifestExecutionHook({
executionSelector: ComprehensivePlugin.foo.selector,
preExecHook: ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
functionId: 1,
dependencyIndex: 0
}),
postExecHook: ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
functionId: 1,
dependencyIndex: 0
})
});

MockPlugin mockPlugin = new MockPlugin(mockPluginManifest);
bytes32 manifestHash = keccak256(abi.encode(mockPlugin.pluginManifest()));

account1.installPlugin(
address(mockPlugin), manifestHash, "", new FunctionReference[](0), new IPluginManager.InjectedHook[](0)
);

// Assert that the returned execution hooks are what is expected

IPluginLoupe.ExecutionHooks[] memory hooks = account1.getExecutionHooks(comprehensivePlugin.foo.selector);

assertEq(hooks.length, 2);
assertEq(
FunctionReference.unwrap(hooks[0].preExecHook),
FunctionReference.unwrap(
FunctionReferenceLib.pack(
address(comprehensivePlugin), uint8(ComprehensivePlugin.FunctionId.PRE_EXECUTION_HOOK)
)
)
);
assertEq(
FunctionReference.unwrap(hooks[0].postExecHook),
FunctionReference.unwrap(
FunctionReferenceLib.pack(
address(comprehensivePlugin), uint8(ComprehensivePlugin.FunctionId.POST_EXECUTION_HOOK)
)
)
);
assertEq(
FunctionReference.unwrap(hooks[1].preExecHook),
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
);
assertEq(
FunctionReference.unwrap(hooks[1].postExecHook),
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
);

// Assert that the returned permitted call hooks are what is expected

hooks = account1.getPermittedCallHooks(address(mockPlugin), comprehensivePlugin.foo.selector);

assertEq(hooks.length, 2);
assertEq(
FunctionReference.unwrap(hooks[0].preExecHook),
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
);
assertEq(
FunctionReference.unwrap(hooks[0].postExecHook),
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
);
assertEq(
FunctionReference.unwrap(hooks[1].preExecHook),
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(1)))
);
assertEq(
FunctionReference.unwrap(hooks[1].postExecHook),
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(1)))
);
}

function test_pluginLoupe_getPreUserOpValidationHooks() public {
FunctionReference[] memory hooks = account1.getPreUserOpValidationHooks(comprehensivePlugin.foo.selector);

Expand Down