Skip to content

Commit aca4ece

Browse files
committed
Fix loop increment issue and add test
1 parent 1f32009 commit aca4ece

2 files changed

Lines changed: 107 additions & 2 deletions

File tree

src/account/BaseModularAccountLoupe.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ abstract contract BaseModularAccountLoupe is IPluginLoupe {
5959
uint256 numHooks = preExecHooks.length;
6060
execHooks = new ExecutionHooks[](numHooks);
6161

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

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

91-
for (uint256 i = 0; i < numHooks; i++) {
91+
for (uint256 i = 0; i < numHooks;) {
9292
execHooks[i].preExecHook = prePermittedCallHooks[i];
9393
execHooks[i].postExecHook =
9494
_storage.permittedCalls[key].associatedPostPermittedCallHooks[prePermittedCallHooks[i]];

test/account/ModularAccountLoupe.t.sol

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@ import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.so
99
import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol";
1010
import {ISingleOwnerPlugin} from "../../src/plugins/owner/ISingleOwnerPlugin.sol";
1111
import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol";
12+
import {
13+
ManifestAssociatedFunctionType,
14+
ManifestExecutionHook,
15+
ManifestFunction,
16+
PluginManifest
17+
} from "../../src/interfaces/IPlugin.sol";
1218
import {IPluginLoupe} from "../../src/interfaces/IPluginLoupe.sol";
1319
import {IPluginManager} from "../../src/interfaces/IPluginManager.sol";
1420
import {IStandardExecutor} from "../../src/interfaces/IStandardExecutor.sol";
1521
import {FunctionReference, FunctionReferenceLib} from "../../src/libraries/FunctionReferenceLib.sol";
1622

1723
import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol";
1824
import {ComprehensivePlugin} from "../mocks/plugins/ComprehensivePlugin.sol";
25+
import {MockPlugin} from "../mocks/MockPlugin.sol";
1926

2027
contract ModularAccountLoupeTest is Test {
2128
EntryPoint public entryPoint;
@@ -189,6 +196,104 @@ contract ModularAccountLoupeTest is Test {
189196
);
190197
}
191198

199+
function test_pluginLoupe_getHooks_multiple() public {
200+
// Add a second set of execution hooks to the account, and validate that it can return all hooks applied
201+
// over the function.
202+
203+
PluginManifest memory mockPluginManifest;
204+
205+
mockPluginManifest.executionHooks = new ManifestExecutionHook[](1);
206+
mockPluginManifest.executionHooks[0] = ManifestExecutionHook({
207+
executionSelector: ComprehensivePlugin.foo.selector,
208+
preExecHook: ManifestFunction({
209+
functionType: ManifestAssociatedFunctionType.SELF,
210+
functionId: 0,
211+
dependencyIndex: 0
212+
}),
213+
postExecHook: ManifestFunction({
214+
functionType: ManifestAssociatedFunctionType.SELF,
215+
functionId: 0,
216+
dependencyIndex: 0
217+
})
218+
});
219+
220+
mockPluginManifest.permittedCallHooks = new ManifestExecutionHook[](2);
221+
// Copy over the same hooks from executionHooks.
222+
mockPluginManifest.permittedCallHooks[0] = mockPluginManifest.executionHooks[0];
223+
mockPluginManifest.permittedCallHooks[1] = ManifestExecutionHook({
224+
executionSelector: ComprehensivePlugin.foo.selector,
225+
preExecHook: ManifestFunction({
226+
functionType: ManifestAssociatedFunctionType.SELF,
227+
functionId: 1,
228+
dependencyIndex: 0
229+
}),
230+
postExecHook: ManifestFunction({
231+
functionType: ManifestAssociatedFunctionType.SELF,
232+
functionId: 1,
233+
dependencyIndex: 0
234+
})
235+
});
236+
237+
MockPlugin mockPlugin = new MockPlugin(mockPluginManifest);
238+
bytes32 manifestHash = keccak256(abi.encode(mockPlugin.pluginManifest()));
239+
240+
account1.installPlugin(
241+
address(mockPlugin), manifestHash, "", new FunctionReference[](0), new IPluginManager.InjectedHook[](0)
242+
);
243+
244+
// Assert that the returned execution hooks are what is expected
245+
246+
IPluginLoupe.ExecutionHooks[] memory hooks = account1.getExecutionHooks(comprehensivePlugin.foo.selector);
247+
248+
assertEq(hooks.length, 2);
249+
assertEq(
250+
FunctionReference.unwrap(hooks[0].preExecHook),
251+
FunctionReference.unwrap(
252+
FunctionReferenceLib.pack(
253+
address(comprehensivePlugin), uint8(ComprehensivePlugin.FunctionId.PRE_EXECUTION_HOOK)
254+
)
255+
)
256+
);
257+
assertEq(
258+
FunctionReference.unwrap(hooks[0].postExecHook),
259+
FunctionReference.unwrap(
260+
FunctionReferenceLib.pack(
261+
address(comprehensivePlugin), uint8(ComprehensivePlugin.FunctionId.POST_EXECUTION_HOOK)
262+
)
263+
)
264+
);
265+
assertEq(
266+
FunctionReference.unwrap(hooks[1].preExecHook),
267+
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
268+
);
269+
assertEq(
270+
FunctionReference.unwrap(hooks[1].postExecHook),
271+
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
272+
);
273+
274+
// Assert that the returned permitted call hooks are what is expected
275+
276+
hooks = account1.getPermittedCallHooks(address(mockPlugin), comprehensivePlugin.foo.selector);
277+
278+
assertEq(hooks.length, 2);
279+
assertEq(
280+
FunctionReference.unwrap(hooks[0].preExecHook),
281+
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
282+
);
283+
assertEq(
284+
FunctionReference.unwrap(hooks[0].postExecHook),
285+
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0)))
286+
);
287+
assertEq(
288+
FunctionReference.unwrap(hooks[1].preExecHook),
289+
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(1)))
290+
);
291+
assertEq(
292+
FunctionReference.unwrap(hooks[1].postExecHook),
293+
FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(1)))
294+
);
295+
}
296+
192297
function test_pluginLoupe_getPreUserOpValidationHooks() public {
193298
FunctionReference[] memory hooks = account1.getPreUserOpValidationHooks(comprehensivePlugin.foo.selector);
194299

0 commit comments

Comments
 (0)