-
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
[2/n permissions] feat: add permission hooks #68
Conversation
e069b7a
to
73e57f3
Compare
53edb51
to
b183d5a
Compare
function preExecutionHook(uint8 functionId, address sender, uint256 value, bytes calldata data) | ||
external | ||
returns (bytes memory); | ||
function preExecutionHook(uint8 functionId, bytes calldata data) external returns (bytes memory); |
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.
Could you expand on why we need this format change? The old format is capable of encoding a call to executeUserOp
, too.
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.
The hook needs to send both address, uint256, bytes
and PackedUserOp
. With the alternative of having 2 formats for exec hooks, to be safe the plugin would have to implement both hook formats and revert in the other format they're not expecting, but in this case they get reverts for free from failing abi decoding
No strong preference here in format. Overall, would prefer if we did separation by call path - all UOs have to send UO context and exec hooks always have PackedUserOperation, and all runtime exec hooks send msg.sender
msg.data
. Think its a simplification that is a step in the right direction for plugin devs
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.
The original format also benefits from the "free" abi-decoding revert. This format is also missing the user op hash provided by the EntryPoint to the account, and introduces a new, custom format for both calls. I think the original format of "caller, value, data" can just as easily handle the calls to executeUserOp
and to the regular function, so I don't think we need a format change here.
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.
I think I'm misunderstanding something, can you expand? Would we send (msg.sender
, msg.value
, requiresUOContext ? abi.encode(PackedUserOperation) : msg.data
)?
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.
I don't think we need any conditional at all - if it is a call to executeUserOp
, then msg.data
will contain the packed user op.
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.
I see, thanks for explaining! In the UO case, msg.sender and msg.value are known, its not clear to me how useful this information is. If there aren't uses, I'd prefer to leave it out of the standard
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.
But this would add extra behavior into the standard to filter it out. It seems like it's a net increase in complexity to have branching cases, rather than provide the data as-is.
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.
Does it make sense to have a UO exec hook vs runtime exec hook? I think theres a lot of branching cases here already, would love to simplify if possible
As a plugin dev, if they specify that they don't need the UO context, they still need to check and conditionally filter for executeUserOp.selector
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.
Looks good overall! This makes sense as a way to create exec hooks that are associated with a validation, rather than an exec selector.
I think there is 1 missing case that should be implemented here - it is possible to create a validation associated exec hook that does not require UO context, and I think those hooks aren't run currently in executeWithAuthorization
for the runtime case.
@@ -47,15 +41,35 @@ abstract contract AccountLoupe is IAccountLoupe { | |||
override | |||
returns (ExecutionHook[] memory execHooks) | |||
{ | |||
SelectorData storage selectorData = getAccountStorage().selectorData[selector]; | |||
uint256 executionHooksLength = selectorData.executionHooks.length(); | |||
EnumerableSet.Bytes32Set storage hooks = getAccountStorage().selectorData[selector].executionHooks; |
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.
Good catch on simplifying here
} | ||
|
||
/// @inheritdoc IAccountLoupe | ||
function getPermissionHooks(FunctionReference validationFunction) |
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.
It makes sense to also surface these hooks in the loupe. We should consider naming them something other than permission hooks, since some permissions may be implemented elsewhere like pre-validation hooks. OK with this for now.
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.
another one in the list of stuff to rename lol
b183d5a
to
f3ad732
Compare
8f55c1b
to
a1c31ce
Compare
9164020
to
dbcf555
Compare
a1c31ce
to
3941060
Compare
7d9f003
to
3c65bc6
Compare
4f8c2dc
to
5d2c4ff
Compare
3941060
to
ee0a657
Compare
addresses: erc6900/resources#50 |
(For the entire PR stack)
Permission hooks are hooks associated with a validation function. The proposed model of permissions is:
AND
logic)executeUserOp
, and the fullPackedUserOp
struct would be passed to the hookChangelog in this PR:
requireUOContext
toExecutionHook
for plugins to signal that the hook needsPackedUserOperation
string[]
toPluginMetadata
for permission plugins to declare ERC-7715 permission stringsuint8 requireUOHookCount
to track the number of permission hooks to allow a cheap check during validation2 issues that will be addressed in future PRs:
abi.encodePacked(msg.sender, msg.value, msg.data)
orabi.encode(PackedUserOperation)
. As we'll likely transition to composable validation with "entity ids", the final shape of execution hooks relies on that. At the same time, instead of passing inmsg.value
, we should consider passing in an int256 "outgoing value minus incoming value"