-
Notifications
You must be signed in to change notification settings - Fork 25
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
feat: [v0.8-develop] Add allowlist sample hook, refactor test base #70
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.25; | ||
|
||
import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; | ||
|
||
import {PluginMetadata, PluginManifest} from "../../interfaces/IPlugin.sol"; | ||
import {IValidationHook} from "../../interfaces/IValidationHook.sol"; | ||
import {IStandardExecutor, Call} from "../../interfaces/IStandardExecutor.sol"; | ||
import {BasePlugin} from "../../plugins/BasePlugin.sol"; | ||
|
||
contract AllowlistPlugin is IValidationHook, BasePlugin { | ||
enum FunctionId { | ||
PRE_VALIDATION_HOOK | ||
} | ||
|
||
struct AllowlistInit { | ||
address target; | ||
bool hasSelectorAllowlist; | ||
bytes4[] selectors; | ||
} | ||
|
||
struct AllowlistEntry { | ||
bool allowed; | ||
bool hasSelectorAllowlist; | ||
} | ||
|
||
mapping(address target => mapping(address account => AllowlistEntry)) public targetAllowlist; | ||
mapping(address target => mapping(bytes4 selector => mapping(address account => bool))) public | ||
selectorAllowlist; | ||
|
||
error TargetNotAllowed(); | ||
error SelectorNotAllowed(); | ||
error NoSelectorSpecified(); | ||
|
||
function onInstall(bytes calldata data) external override { | ||
AllowlistInit[] memory init = abi.decode(data, (AllowlistInit[])); | ||
|
||
for (uint256 i = 0; i < init.length; i++) { | ||
targetAllowlist[init[i].target][msg.sender] = AllowlistEntry(true, init[i].hasSelectorAllowlist); | ||
|
||
if (init[i].hasSelectorAllowlist) { | ||
for (uint256 j = 0; j < init[i].selectors.length; j++) { | ||
selectorAllowlist[init[i].target][init[i].selectors[j]][msg.sender] = true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
function onUninstall(bytes calldata data) external override { | ||
AllowlistInit[] memory init = abi.decode(data, (AllowlistInit[])); | ||
|
||
for (uint256 i = 0; i < init.length; i++) { | ||
delete targetAllowlist[init[i].target][msg.sender]; | ||
|
||
if (init[i].hasSelectorAllowlist) { | ||
for (uint256 j = 0; j < init[i].selectors.length; j++) { | ||
delete selectorAllowlist[init[i].target][init[i].selectors[j]][msg.sender]; | ||
} | ||
} | ||
} | ||
} | ||
|
||
function setAllowlistTarget(address target, bool allowed, bool hasSelectorAllowlist) external { | ||
targetAllowlist[target][msg.sender] = AllowlistEntry(allowed, hasSelectorAllowlist); | ||
} | ||
|
||
function setAllowlistSelector(address target, bytes4 selector, bool allowed) external { | ||
selectorAllowlist[target][selector][msg.sender] = allowed; | ||
} | ||
|
||
function preUserOpValidationHook(uint8 functionId, PackedUserOperation calldata userOp, bytes32) | ||
external | ||
view | ||
override | ||
returns (uint256) | ||
{ | ||
if (functionId == uint8(FunctionId.PRE_VALIDATION_HOOK)) { | ||
_checkAllowlistCalldata(userOp.callData); | ||
return 0; | ||
} | ||
revert NotImplemented(); | ||
} | ||
|
||
function preRuntimeValidationHook(uint8 functionId, address, uint256, bytes calldata data, bytes calldata) | ||
external | ||
view | ||
override | ||
{ | ||
if (functionId == uint8(FunctionId.PRE_VALIDATION_HOOK)) { | ||
_checkAllowlistCalldata(data); | ||
return; | ||
} | ||
|
||
revert NotImplemented(); | ||
} | ||
|
||
function pluginMetadata() external pure override returns (PluginMetadata memory) { | ||
PluginMetadata memory metadata; | ||
metadata.name = "Allowlist Plugin"; | ||
metadata.version = "v0.0.1"; | ||
metadata.author = "ERC-6900 Working Group"; | ||
|
||
return metadata; | ||
} | ||
|
||
// solhint-disable-next-line no-empty-blocks | ||
function pluginManifest() external pure override returns (PluginManifest memory) {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this blank because it's supposed to only be installed with a user-provided config? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, basically. The manifest is empty because this plugin doesn't define anything that the manifest can install:
|
||
|
||
function _checkAllowlistCalldata(bytes calldata callData) internal view { | ||
if (bytes4(callData[:4]) == IStandardExecutor.execute.selector) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Callout: when executeUserOp is used, we need to check calldata[4:8] instead There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this hook doesn't depend on the contents of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah agree that it should be abstracted from plugins. in the current permissions stack, we directly send over userOp.callData which could be |
||
(address target,, bytes memory data) = abi.decode(callData[4:], (address, uint256, bytes)); | ||
_checkCallPermission(msg.sender, target, data); | ||
} else if (bytes4(callData[:4]) == IStandardExecutor.executeBatch.selector) { | ||
Call[] memory calls = abi.decode(callData[4:], (Call[])); | ||
|
||
for (uint256 i = 0; i < calls.length; i++) { | ||
_checkCallPermission(msg.sender, calls[i].target, calls[i].data); | ||
} | ||
} | ||
} | ||
|
||
function _checkCallPermission(address account, address target, bytes memory data) internal view { | ||
AllowlistEntry storage entry = targetAllowlist[target][account]; | ||
(bool allowed, bool hasSelectorAllowlist) = (entry.allowed, entry.hasSelectorAllowlist); | ||
|
||
if (!allowed) { | ||
revert TargetNotAllowed(); | ||
} | ||
|
||
if (hasSelectorAllowlist) { | ||
if (data.length < 4) { | ||
revert NoSelectorSpecified(); | ||
} | ||
|
||
bytes4 selector = bytes4(data); | ||
|
||
if (!selectorAllowlist[target][selector][account]) { | ||
revert SelectorNotAllowed(); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,63 +3,28 @@ pragma solidity ^0.8.25; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {ISingleOwnerPlugin} from "../../src/plugins/owner/ISingleOwnerPlugin.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {FunctionReference, FunctionReferenceLib} from "../../src/helpers/FunctionReferenceLib.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {MockAccessControlHookPlugin} from "../mocks/plugins/MockAccessControlHookPlugin.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {Counter} from "../mocks/Counter.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {AccountTestBase} from "../utils/AccountTestBase.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {CustomValidationTestBase} from "../utils/CustomValidationTestBase.sol"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
contract PerHookDataTest is AccountTestBase { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
contract PerHookDataTest is CustomValidationTestBase { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
using MessageHashUtils for bytes32; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MockAccessControlHookPlugin internal _accessControlHookPlugin; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Counter internal _counter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FunctionReference internal _ownerValidation; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint256 public constant CALL_GAS_LIMIT = 50000; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint256 public constant VERIFICATION_GAS_LIMIT = 1200000; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function setUp() public { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_counter = new Counter(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_accessControlHookPlugin = new MockAccessControlHookPlugin(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Write over `account1` with a new account proxy, with different initialization. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
address accountImplementation = address(factory.accountImplementation()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
account1 = UpgradeableModularAccount(payable(new ERC1967Proxy(accountImplementation, ""))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_ownerValidation = FunctionReferenceLib.pack( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
address(singleOwnerPlugin), uint8(ISingleOwnerPlugin.FunctionId.VALIDATION_OWNER) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FunctionReference accessControlHook = FunctionReferenceLib.pack( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
address(_accessControlHookPlugin), uint8(MockAccessControlHookPlugin.FunctionId.PRE_VALIDATION_HOOK) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FunctionReference[] memory preValidationHooks = new FunctionReference[](1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
preValidationHooks[0] = accessControlHook; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes[] memory preValidationHookData = new bytes[](1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Access control is restricted to only the _counter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
preValidationHookData[0] = abi.encode(_counter); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes memory packedPreValidationHooks = abi.encode(preValidationHooks, preValidationHookData); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vm.prank(address(entryPoint)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
account1.installValidation( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_ownerValidation, true, new bytes4[](0), abi.encode(owner1), packedPreValidationHooks, "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
vm.deal(address(account1), 100 ether); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_customValidationSetup(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do the old tests here test allowList fails? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, depending on the call path, they throw either user op or runtime errors, and the fuzzer expects them to be called. The error to look for is loaded from here: reference-implementation/test/samples/AllowlistPlugin.t.sol Lines 142 to 199 in 8c7133c
And the test expects them here:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function test_passAccessControl_userOp() public { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -358,4 +323,28 @@ contract PerHookDataTest is AccountTestBase { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return (userOp, userOpHash); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Test config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function _initialValidationConfig() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
internal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
virtual | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
returns (FunctionReference, bool, bytes4[] memory, bytes memory, bytes memory, bytes memory) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FunctionReference accessControlHook = FunctionReferenceLib.pack( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
address(_accessControlHookPlugin), uint8(MockAccessControlHookPlugin.FunctionId.PRE_VALIDATION_HOOK) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FunctionReference[] memory preValidationHooks = new FunctionReference[](1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
preValidationHooks[0] = accessControlHook; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes[] memory preValidationHookData = new bytes[](1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Access control is restricted to only the counter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
preValidationHookData[0] = abi.encode(_counter); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes memory packedPreValidationHooks = abi.encode(preValidationHooks, preValidationHookData); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return (_ownerValidation, true, new bytes4[](0), abi.encode(owner1), packedPreValidationHooks, ""); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point of this check, and the similar one in the runtime validation hook?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other plugin examples we've been using an if-else chain for the internal function dispatcher, so I was following that pattern here too. I suppose we could cut it and just treat every function id the same here, because this one doesn't have multiple implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like the idea of not having the functionId, especially the plugins are global singleton.Actually, we should be explicit since we do ask the
functionId
var to be passed.