From 08e19131a2635f0138d5e57a1f9a47a65ce2388d Mon Sep 17 00:00:00 2001 From: leekt Date: Fri, 10 Nov 2023 01:13:17 +0900 Subject: [PATCH] added delegatecall support --- src/Kernel.sol | 16 ++++++++++++++++ test/foundry/KernelTestBase.sol | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Kernel.sol b/src/Kernel.sol index 6275f5cb..4dacbb01 100644 --- a/src/Kernel.sol +++ b/src/Kernel.sol @@ -75,6 +75,22 @@ contract Kernel is EIP712, Compatibility, KernelStorage { default { return(0, returndatasize()) } } } + + /// @notice Executes a function call to an external contract with delegatecall + /// @param to The address of the target contract + /// @param data The call data to be sent + function executeDelegateCall(address to, bytes memory data) external payable { + if (msg.sender != address(entryPoint) && msg.sender != address(this) && !_checkCaller()) { + revert NotAuthorizedCaller(); + } + assembly { + let success := delegatecall(gas(), to, add(data, 0x20), mload(data), 0, 0) + returndatacopy(0, 0, returndatasize()) + switch success + case 0 { revert(0, returndatasize()) } + default { return(0, returndatasize()) } + } + } /// @notice Executes a function call to an external contract batched /// @param calls The calls to be executed, in order diff --git a/test/foundry/KernelTestBase.sol b/test/foundry/KernelTestBase.sol index baa2d42d..585ac0a1 100644 --- a/test/foundry/KernelTestBase.sol +++ b/test/foundry/KernelTestBase.sol @@ -96,8 +96,24 @@ abstract contract KernelTestBase is Test { kernel.execute(validCallers[i], 0, "", Operation.Call); } } - + + function test_external_call_execute_delegatecall_success() external { + address[] memory validCallers = getOwners(); + for (uint256 i = 0; i < validCallers.length; i++) { + vm.prank(validCallers[i]); + kernel.executeDelegateCall(validCallers[i], ""); + } + } function test_external_call_execute_delegatecall_fail() external { + address[] memory validCallers = getOwners(); + for (uint256 i = 0; i < validCallers.length; i++) { + vm.prank(address(uint160(validCallers[i]) + 1)); + vm.expectRevert(); + kernel.executeDelegateCall(validCallers[i], ""); + } + } + + function test_external_call_execute_delegatecall_option_fail() external { address[] memory validCallers = getOwners(); for (uint256 i = 0; i < validCallers.length; i++) { vm.prank(validCallers[i]);