Skip to content

Commit

Permalink
feat: overridable token receivers (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaypaik authored and howydev committed Feb 2, 2024
1 parent a8c1264 commit f1ab973
Showing 1 changed file with 57 additions and 15 deletions.
72 changes: 57 additions & 15 deletions src/account/UpgradeableModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -377,54 +377,61 @@ contract UpgradeableModularAccount is
/// @inheritdoc IERC777Recipient
/// @dev Runtime validation is bypassed for this function, but we still allow pre and post exec hooks to be
/// assigned and run.
function tokensReceived(address, address, address, uint256, bytes calldata, bytes calldata)
external
override
{
function tokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
(FunctionReference[][] memory postExecHooks, bytes[] memory postHookArgs) =
_doPreExecHooks(_getAccountStorage().selectorData[msg.sig], "");
_tokensReceived(operator, from, to, amount, userData, operatorData);
_postNativeFunction(postExecHooks, postHookArgs);
}

/// @inheritdoc IERC721Receiver
/// @dev Runtime validation is bypassed for this function, but we still allow pre and post exec hooks to be
/// assigned and run.
function onERC721Received(address, address, uint256, bytes calldata)
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data)
external
override
returns (bytes4 selector)
{
(FunctionReference[][] memory postExecHooks, bytes[] memory postHookArgs) =
_doPreExecHooks(_getAccountStorage().selectorData[msg.sig], "");
selector = IERC721Receiver.onERC721Received.selector;
selector = _onERC721Received(operator, from, tokenId, data);
_postNativeFunction(postExecHooks, postHookArgs);
}

/// @inheritdoc IERC1155Receiver
/// @dev Runtime validation is bypassed for this function, but we still allow pre and post exec hooks to be
/// assigned and run.
function onERC1155Received(address, address, uint256, uint256, bytes calldata)
function onERC1155Received(address operator, address from, uint256 id, uint256 value, bytes calldata data)
external
override
returns (bytes4 selector)
{
(FunctionReference[][] memory postExecHooks, bytes[] memory postHookArgs) =
_doPreExecHooks(_getAccountStorage().selectorData[msg.sig], "");
selector = IERC1155Receiver.onERC1155Received.selector;
selector = _onERC1155Received(operator, from, id, value, data);
_postNativeFunction(postExecHooks, postHookArgs);
}

/// @inheritdoc IERC1155Receiver
/// @dev Runtime validation is bypassed for this function, but we still allow pre and post exec hooks to be
/// assigned and run.
function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata)
external
override
returns (bytes4 selector)
{
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external override returns (bytes4 selector) {
(FunctionReference[][] memory postExecHooks, bytes[] memory postHookArgs) =
_doPreExecHooks(_getAccountStorage().selectorData[msg.sig], "");
selector = IERC1155Receiver.onERC1155BatchReceived.selector;
selector = _onERC1155BatchReceived(operator, from, ids, values, data);
_postNativeFunction(postExecHooks, postHookArgs);
}

Expand Down Expand Up @@ -672,7 +679,8 @@ contract UpgradeableModularAccount is
if (callBuffer.length == 0) {
// Allocate the call buffer for preExecHook. This case MUST NOT be reached by `executeFromPlugin`,
// otherwise the call will execute with the wrong calldata. This case should only be reachable by
// native functions with no runtime validation (i.e. being calling via a user operation).
// native functions with no runtime validation (e.g., token receiver functions or functions called via
// a user operation).
callBuffer = _allocateRuntimeCallBuffer(msg.data);
}
_updatePluginCallBufferSelector(callBuffer, IPlugin.preExecutionHook.selector);
Expand Down Expand Up @@ -739,6 +747,40 @@ contract UpgradeableModularAccount is
// solhint-disable-next-line no-empty-blocks
function _authorizeUpgrade(address newImplementation) internal override {}

/// @dev Override to implement custom behavior.
function _tokensReceived(address, address, address, uint256, bytes calldata, bytes calldata)
internal
virtual
// solhint-disable-next-line no-empty-blocks
{}

/// @dev Override to implement custom behavior.
function _onERC721Received(address, address, uint256, bytes calldata)
internal
virtual
returns (bytes4 selector)
{
selector = IERC721Receiver.onERC721Received.selector;
}

/// @dev Override to implement custom behavior.
function _onERC1155Received(address, address, uint256, uint256, bytes calldata)
internal
virtual
returns (bytes4 selector)
{
selector = IERC1155Receiver.onERC1155Received.selector;
}

/// @dev Override to implement custom behavior.
function _onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata)
internal
virtual
returns (bytes4 selector)
{
selector = IERC1155Receiver.onERC1155BatchReceived.selector;
}

/// @dev Loads the associated post hooks for the given pre-exec hooks in the `postHooks` array, starting at 0.
function _cacheAssociatedPostHooks(
FunctionReference[] memory preExecHooks,
Expand Down

0 comments on commit f1ab973

Please sign in to comment.