From 3297aa6f55f163961486740cf47a5c857386506e Mon Sep 17 00:00:00 2001 From: KONFeature Date: Sat, 25 Nov 2023 22:51:09 +0100 Subject: [PATCH 1/4] Add storage slot documentation & run coverage --- .gas-snapshot | 179 ++++++++++++++++++++++++++++++++++----- src/Kernel.sol | 1 + src/common/Constants.sol | 12 ++- 3 files changed, 170 insertions(+), 22 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index cc7d5bdc..0d1fe00f 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,19 +1,160 @@ -KernelExecutionTest:test_mode_2() (gas: 593614) -KernelExecutionTest:test_mode_2() (gas: 611256) -KernelExecutionTest:test_mode_2_1() (gas: 589400) -KernelExecutionTest:test_mode_2_erc165() (gas: 2485466) -KernelExecutionTest:test_revert_when_mode_disabled() (gas: 192767) -KernelExecutionTest:test_sudo() (gas: 216219) -KernelHelperTest:testIntersect(uint48,uint48,uint48,uint48) (runs: 256, μ: 2379, ~: 2383) -KernelTest:test_disable_mode() (gas: 170757) -KernelTest:test_disable_mode() (gas: 172824) -KernelTest:test_external_call_default() (gas: 28844) -KernelTest:test_external_call_execution() (gas: 520197) -KernelTest:test_initialize_twice() (gas: 20515) -KernelTest:test_initialize_twice() (gas: 20537) -KernelTest:test_set_default_validator() (gas: 427634) -KernelTest:test_set_default_validator() (gas: 429679) -KernelTest:test_set_execution() (gas: 477930) -KernelTest:test_set_execution() (gas: 479975) -KernelTest:test_validate_signature() (gas: 171911) -KernelTest:test_validate_signature() (gas: 175529) \ No newline at end of file +KernelECDSATest:test_default_validator_disable() (gas: 0) +KernelECDSATest:test_default_validator_disable() (gas: 180315) +KernelECDSATest:test_default_validator_enable() (gas: 0) +KernelECDSATest:test_default_validator_enable() (gas: 187804) +KernelECDSATest:test_disable_mode() (gas: 182799) +KernelECDSATest:test_disable_mode() (gas: 192124) +KernelECDSATest:test_eip712() (gas: 15684) +KernelECDSATest:test_eip712() (gas: 15684) +KernelECDSATest:test_enable_then_mode_1() (gas: 278034) +KernelECDSATest:test_enable_then_mode_1() (gas: 286105) +KernelECDSATest:test_external_call_batch_execute_fail() (gas: 23628) +KernelECDSATest:test_external_call_batch_execute_fail() (gas: 29589) +KernelECDSATest:test_external_call_batch_execute_success() (gas: 20629) +KernelECDSATest:test_external_call_batch_execute_success() (gas: 26536) +KernelECDSATest:test_external_call_default() (gas: 23511) +KernelECDSATest:test_external_call_default() (gas: 29338) +KernelECDSATest:test_external_call_execute_delegatecall_fail() (gas: 22499) +KernelECDSATest:test_external_call_execute_delegatecall_fail() (gas: 28436) +KernelECDSATest:test_external_call_execute_delegatecall_option_fail() (gas: 20434) +KernelECDSATest:test_external_call_execute_delegatecall_option_fail() (gas: 26329) +KernelECDSATest:test_external_call_execute_delegatecall_success() (gas: 19738) +KernelECDSATest:test_external_call_execute_delegatecall_success() (gas: 25621) +KernelECDSATest:test_external_call_execute_fail() (gas: 21968) +KernelECDSATest:test_external_call_execute_fail() (gas: 27917) +KernelECDSATest:test_external_call_execute_success() (gas: 20070) +KernelECDSATest:test_external_call_execute_success() (gas: 25987) +KernelECDSATest:test_external_call_execution() (gas: 497864) +KernelECDSATest:test_external_call_execution() (gas: 510810) +KernelECDSATest:test_fail_validate_not_activate() (gas: 0) +KernelECDSATest:test_fail_validate_not_activate() (gas: 303491) +KernelECDSATest:test_fail_validate_wrongsignature() (gas: 24904) +KernelECDSATest:test_fail_validate_wrongsignature() (gas: 34133) +KernelECDSATest:test_get_nonce() (gas: 25179) +KernelECDSATest:test_get_nonce() (gas: 25201) +KernelECDSATest:test_get_nonce(uint192) (runs: 1024, μ: 19842, ~: 19842) +KernelECDSATest:test_get_nonce(uint192) (runs: 1024, μ: 19842, ~: 19842) +KernelECDSATest:test_ignore() (gas: 868) +KernelECDSATest:test_initialize() (gas: 126784) +KernelECDSATest:test_initialize() (gas: 154121) +KernelECDSATest:test_initialize_twice() (gas: 18555) +KernelECDSATest:test_initialize_twice() (gas: 18698) +KernelECDSATest:test_mode_2() (gas: 243033) +KernelECDSATest:test_mode_2() (gas: 250224) +KernelECDSATest:test_revert_when_mode_disabled() (gas: 201237) +KernelECDSATest:test_revert_when_mode_disabled() (gas: 210562) +KernelECDSATest:test_set_default_validator() (gas: 417190) +KernelECDSATest:test_set_default_validator() (gas: 423339) +KernelECDSATest:test_set_execution() (gas: 458187) +KernelECDSATest:test_set_execution() (gas: 468307) +KernelECDSATest:test_should_emit_event_on_receive() (gas: 23220) +KernelECDSATest:test_should_emit_event_on_receive() (gas: 23220) +KernelECDSATest:test_should_receive_erc1155() (gas: 701145) +KernelECDSATest:test_should_receive_erc1155() (gas: 701171) +KernelECDSATest:test_should_receive_erc1155_batch() (gas: 728411) +KernelECDSATest:test_should_receive_erc1155_batch() (gas: 728411) +KernelECDSATest:test_should_receive_erc721() (gas: 597680) +KernelECDSATest:test_should_receive_erc721() (gas: 597702) +KernelECDSATest:test_should_return_address_if_deployed() (gas: 21970) +KernelECDSATest:test_should_return_address_if_deployed() (gas: 21976) +KernelECDSATest:test_sudo() (gas: 170047) +KernelECDSATest:test_sudo() (gas: 179454) +KernelECDSATest:test_sudo_wrongSig() (gas: 102568) +KernelECDSATest:test_sudo_wrongSig() (gas: 115756) +KernelECDSATest:test_transfer_ownership() (gas: 178443) +KernelECDSATest:test_upgrade() (gas: 21292) +KernelECDSATest:test_upgrade() (gas: 21292) +KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28722) +KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28722) +KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30588) +KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30631) +KernelECDSATest:test_validate_signature() (gas: 155714) +KernelECDSATest:test_validate_signature() (gas: 194502) +KernelHelperTest:testIntersect(uint48,uint48,uint48,uint48) (runs: 1024, μ: 871, ~: 869) +KillSwitchValidatorTest:test_default_validator_disable() (gas: 180479) +KillSwitchValidatorTest:test_default_validator_enable() (gas: 187968) +KillSwitchValidatorTest:test_disable_mode() (gas: 182963) +KillSwitchValidatorTest:test_eip712() (gas: 15820) +KillSwitchValidatorTest:test_enable_then_mode_1() (gas: 348628) +KillSwitchValidatorTest:test_external_call_batch_execute_fail() (gas: 29677) +KillSwitchValidatorTest:test_external_call_batch_execute_success() (gas: 26558) +KillSwitchValidatorTest:test_external_call_default() (gas: 29426) +KillSwitchValidatorTest:test_external_call_execute_delegatecall_fail() (gas: 28524) +KillSwitchValidatorTest:test_external_call_execute_delegatecall_option_fail() (gas: 26439) +KillSwitchValidatorTest:test_external_call_execute_delegatecall_success() (gas: 25709) +KillSwitchValidatorTest:test_external_call_execute_fail() (gas: 27961) +KillSwitchValidatorTest:test_external_call_execute_success() (gas: 26075) +KillSwitchValidatorTest:test_external_call_execution() (gas: 510974) +KillSwitchValidatorTest:test_fail_validate_not_activate() (gas: 303601) +KillSwitchValidatorTest:test_fail_validate_wrongsignature() (gas: 34276) +KillSwitchValidatorTest:test_force_unblock() (gas: 391619) +KillSwitchValidatorTest:test_get_nonce() (gas: 25201) +KillSwitchValidatorTest:test_get_nonce(uint192) (runs: 1024, μ: 19930, ~: 19930) +KillSwitchValidatorTest:test_ignore() (gas: 956) +KillSwitchValidatorTest:test_initialize() (gas: 154209) +KillSwitchValidatorTest:test_initialize_twice() (gas: 18643) +KillSwitchValidatorTest:test_mode_2() (gas: 312742) +KillSwitchValidatorTest:test_revert_when_mode_disabled() (gas: 201434) +KillSwitchValidatorTest:test_set_default_validator() (gas: 423481) +KillSwitchValidatorTest:test_set_execution() (gas: 468471) +KillSwitchValidatorTest:test_should_emit_event_on_receive() (gas: 23330) +KillSwitchValidatorTest:test_should_fail_with_not_implemented_isValidSignature() (gas: 9236) +KillSwitchValidatorTest:test_should_fail_with_not_implemented_isValidSignature(bytes32,bytes) (runs: 1024, μ: 9601, ~: 9556) +KillSwitchValidatorTest:test_should_fail_with_not_implemented_validCaller() (gas: 10157) +KillSwitchValidatorTest:test_should_fail_with_not_implemented_validCaller(address,bytes) (runs: 1024, μ: 9749, ~: 9703) +KillSwitchValidatorTest:test_should_receive_erc1155() (gas: 701233) +KillSwitchValidatorTest:test_should_receive_erc1155_batch() (gas: 728499) +KillSwitchValidatorTest:test_should_receive_erc721() (gas: 597790) +KillSwitchValidatorTest:test_should_return_address_if_deployed() (gas: 22086) +KillSwitchValidatorTest:test_sudo() (gas: 179596) +KillSwitchValidatorTest:test_sudo_wrongSig() (gas: 115877) +KillSwitchValidatorTest:test_upgrade() (gas: 21314) +KillSwitchValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28810) +KillSwitchValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30705) +KillSwitchValidatorTest:test_validate_signature() (gas: 194579) +SessionKeyValidatorTest:test_default_validator_disable() (gas: 180358) +SessionKeyValidatorTest:test_default_validator_enable() (gas: 187847) +SessionKeyValidatorTest:test_disable_mode() (gas: 182842) +SessionKeyValidatorTest:test_eip712() (gas: 15684) +SessionKeyValidatorTest:test_enable_then_mode_1() (gas: 286170) +SessionKeyValidatorTest:test_external_call_batch_execute_fail() (gas: 29589) +SessionKeyValidatorTest:test_external_call_batch_execute_success() (gas: 26536) +SessionKeyValidatorTest:test_external_call_default() (gas: 29338) +SessionKeyValidatorTest:test_external_call_execute_delegatecall_fail() (gas: 28436) +SessionKeyValidatorTest:test_external_call_execute_delegatecall_option_fail() (gas: 26351) +SessionKeyValidatorTest:test_external_call_execute_delegatecall_success() (gas: 25621) +SessionKeyValidatorTest:test_external_call_execute_fail() (gas: 27917) +SessionKeyValidatorTest:test_external_call_execute_success() (gas: 26009) +SessionKeyValidatorTest:test_external_call_execution() (gas: 510875) +SessionKeyValidatorTest:test_fail_validate_not_activate() (gas: 303513) +SessionKeyValidatorTest:test_fail_validate_wrongsignature() (gas: 34165) +SessionKeyValidatorTest:test_get_nonce() (gas: 25179) +SessionKeyValidatorTest:test_get_nonce(uint192) (runs: 1024, μ: 19842, ~: 19842) +SessionKeyValidatorTest:test_ignore() (gas: 890) +SessionKeyValidatorTest:test_initialize() (gas: 154121) +SessionKeyValidatorTest:test_initialize_twice() (gas: 18555) +SessionKeyValidatorTest:test_mode_2() (gas: 250279) +SessionKeyValidatorTest:test_revert_when_mode_disabled() (gas: 201280) +SessionKeyValidatorTest:test_scenario_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool),(uint8)) (runs: 1024, μ: 43221909, ~: 31867213) +SessionKeyValidatorTest:test_scenario_non_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool)) (runs: 1024, μ: 17443341, ~: 16183886) +SessionKeyValidatorTest:test_set_default_validator() (gas: 423382) +SessionKeyValidatorTest:test_set_execution() (gas: 468350) +SessionKeyValidatorTest:test_should_emit_event_on_receive() (gas: 23242) +SessionKeyValidatorTest:test_should_receive_erc1155() (gas: 701145) +SessionKeyValidatorTest:test_should_receive_erc1155_batch() (gas: 728411) +SessionKeyValidatorTest:test_should_receive_erc721() (gas: 597724) +SessionKeyValidatorTest:test_should_return_address_if_deployed() (gas: 22003) +SessionKeyValidatorTest:test_sudo() (gas: 179497) +SessionKeyValidatorTest:test_sudo_wrongSig() (gas: 115778) +SessionKeyValidatorTest:test_upgrade() (gas: 21292) +SessionKeyValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28746) +SessionKeyValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30631) +SessionKeyValidatorTest:test_validate_signature() (gas: 194502) +TestCallee:test_ignore() (gas: 206) +TestCounter:test_ignore() (gas: 164) +TestERC1155:test_ignore() (gas: 328) +TestERC20:test_ignore() (gas: 389) +TestERC721:test_ignore() (gas: 399) +TestExecutor:test_ignore() (gas: 130) +TestPaymaster:test_ignore() (gas: 174) +TestValidator:test_ignore() (gas: 351) \ No newline at end of file diff --git a/src/Kernel.sol b/src/Kernel.sol index 9687c120..ffbf975e 100644 --- a/src/Kernel.sol +++ b/src/Kernel.sol @@ -159,6 +159,7 @@ contract Kernel is EIP712, Compatibility, KernelStorage { IKernelValidator validator; bytes32 storage_slot_1; assembly { + // sslot 1 contain default validator, disabled mode & disabled date storage_slot_1 := sload(KERNEL_STORAGE_SLOT_1) } if (mode & (storage_slot_1 << 224) != 0x00000000) { diff --git a/src/common/Constants.sol b/src/common/Constants.sol index e85dc7f3..35bf3408 100644 --- a/src/common/Constants.sol +++ b/src/common/Constants.sol @@ -13,7 +13,13 @@ ValidationData constant SIG_VALIDATION_FAILED = ValidationData.wrap(SIG_VALIDATI // STRUCT_HASH bytes32 constant VALIDATOR_APPROVED_STRUCT_HASH = 0x3ce406685c1b3551d706d85a68afdaa49ac4e07b451ad9b8ff8b58c3ee964176; -// Storage slots -bytes32 constant KERNEL_STORAGE_SLOT = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd8; -bytes32 constant KERNEL_STORAGE_SLOT_1 = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd9; +/* -------------------------------------------------------------------------- */ +/* Storage slots */ +/* -------------------------------------------------------------------------- */ + +/// @dev Storage slot for the kernel storage +bytes32 constant KERNEL_STORAGE_SLOT = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd8; +/// @dev Storage pointer inside the kernel storage, with 1 offset, to access directly disblaedMode, disabled date and default validator +bytes32 constant KERNEL_STORAGE_SLOT_1 = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd9; +/// @dev Storage slot for the logic implementation address bytes32 constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; From ba42cef516ef20053949b4a62605505a5b581e95 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Sat, 25 Nov 2023 23:09:31 +0100 Subject: [PATCH 2/4] Gas improvment on disabled mode check during execution Between 1 to 22% gas saved during userOp execution --- .gas-snapshot | 108 +++++++++++++++++++-------------------- src/Kernel.sol | 35 +++++++++---- src/common/Constants.sol | 2 +- 3 files changed, 79 insertions(+), 66 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 0d1fe00f..0b3aff9c 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,13 +1,13 @@ KernelECDSATest:test_default_validator_disable() (gas: 0) -KernelECDSATest:test_default_validator_disable() (gas: 180315) +KernelECDSATest:test_default_validator_disable() (gas: 180304) KernelECDSATest:test_default_validator_enable() (gas: 0) -KernelECDSATest:test_default_validator_enable() (gas: 187804) -KernelECDSATest:test_disable_mode() (gas: 182799) -KernelECDSATest:test_disable_mode() (gas: 192124) +KernelECDSATest:test_default_validator_enable() (gas: 187793) +KernelECDSATest:test_disable_mode() (gas: 182788) +KernelECDSATest:test_disable_mode() (gas: 192110) KernelECDSATest:test_eip712() (gas: 15684) KernelECDSATest:test_eip712() (gas: 15684) -KernelECDSATest:test_enable_then_mode_1() (gas: 278034) -KernelECDSATest:test_enable_then_mode_1() (gas: 286105) +KernelECDSATest:test_enable_then_mode_1() (gas: 277977) +KernelECDSATest:test_enable_then_mode_1() (gas: 286051) KernelECDSATest:test_external_call_batch_execute_fail() (gas: 23628) KernelECDSATest:test_external_call_batch_execute_fail() (gas: 29589) KernelECDSATest:test_external_call_batch_execute_success() (gas: 20629) @@ -24,8 +24,8 @@ KernelECDSATest:test_external_call_execute_fail() (gas: 21968) KernelECDSATest:test_external_call_execute_fail() (gas: 27917) KernelECDSATest:test_external_call_execute_success() (gas: 20070) KernelECDSATest:test_external_call_execute_success() (gas: 25987) -KernelECDSATest:test_external_call_execution() (gas: 497864) -KernelECDSATest:test_external_call_execution() (gas: 510810) +KernelECDSATest:test_external_call_execution() (gas: 497850) +KernelECDSATest:test_external_call_execution() (gas: 510799) KernelECDSATest:test_fail_validate_not_activate() (gas: 0) KernelECDSATest:test_fail_validate_not_activate() (gas: 303491) KernelECDSATest:test_fail_validate_wrongsignature() (gas: 24904) @@ -39,14 +39,14 @@ KernelECDSATest:test_initialize() (gas: 126784) KernelECDSATest:test_initialize() (gas: 154121) KernelECDSATest:test_initialize_twice() (gas: 18555) KernelECDSATest:test_initialize_twice() (gas: 18698) -KernelECDSATest:test_mode_2() (gas: 243033) -KernelECDSATest:test_mode_2() (gas: 250224) -KernelECDSATest:test_revert_when_mode_disabled() (gas: 201237) -KernelECDSATest:test_revert_when_mode_disabled() (gas: 210562) -KernelECDSATest:test_set_default_validator() (gas: 417190) -KernelECDSATest:test_set_default_validator() (gas: 423339) -KernelECDSATest:test_set_execution() (gas: 458187) -KernelECDSATest:test_set_execution() (gas: 468307) +KernelECDSATest:test_mode_2() (gas: 242990) +KernelECDSATest:test_mode_2() (gas: 250181) +KernelECDSATest:test_revert_when_mode_disabled() (gas: 198987) +KernelECDSATest:test_revert_when_mode_disabled() (gas: 208309) +KernelECDSATest:test_set_default_validator() (gas: 417176) +KernelECDSATest:test_set_default_validator() (gas: 423328) +KernelECDSATest:test_set_execution() (gas: 458173) +KernelECDSATest:test_set_execution() (gas: 468296) KernelECDSATest:test_should_emit_event_on_receive() (gas: 23220) KernelECDSATest:test_should_emit_event_on_receive() (gas: 23220) KernelECDSATest:test_should_receive_erc1155() (gas: 701145) @@ -57,25 +57,25 @@ KernelECDSATest:test_should_receive_erc721() (gas: 597680) KernelECDSATest:test_should_receive_erc721() (gas: 597702) KernelECDSATest:test_should_return_address_if_deployed() (gas: 21970) KernelECDSATest:test_should_return_address_if_deployed() (gas: 21976) -KernelECDSATest:test_sudo() (gas: 170047) -KernelECDSATest:test_sudo() (gas: 179454) -KernelECDSATest:test_sudo_wrongSig() (gas: 102568) -KernelECDSATest:test_sudo_wrongSig() (gas: 115756) -KernelECDSATest:test_transfer_ownership() (gas: 178443) +KernelECDSATest:test_sudo() (gas: 170033) +KernelECDSATest:test_sudo() (gas: 179443) +KernelECDSATest:test_sudo_wrongSig() (gas: 102554) +KernelECDSATest:test_sudo_wrongSig() (gas: 115745) +KernelECDSATest:test_transfer_ownership() (gas: 178429) KernelECDSATest:test_upgrade() (gas: 21292) KernelECDSATest:test_upgrade() (gas: 21292) -KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28722) -KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28722) -KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30588) -KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30631) +KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28679) +KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28679) +KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30582) +KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30625) KernelECDSATest:test_validate_signature() (gas: 155714) KernelECDSATest:test_validate_signature() (gas: 194502) KernelHelperTest:testIntersect(uint48,uint48,uint48,uint48) (runs: 1024, μ: 871, ~: 869) -KillSwitchValidatorTest:test_default_validator_disable() (gas: 180479) -KillSwitchValidatorTest:test_default_validator_enable() (gas: 187968) -KillSwitchValidatorTest:test_disable_mode() (gas: 182963) +KillSwitchValidatorTest:test_default_validator_disable() (gas: 180468) +KillSwitchValidatorTest:test_default_validator_enable() (gas: 187957) +KillSwitchValidatorTest:test_disable_mode() (gas: 182952) KillSwitchValidatorTest:test_eip712() (gas: 15820) -KillSwitchValidatorTest:test_enable_then_mode_1() (gas: 348628) +KillSwitchValidatorTest:test_enable_then_mode_1() (gas: 348574) KillSwitchValidatorTest:test_external_call_batch_execute_fail() (gas: 29677) KillSwitchValidatorTest:test_external_call_batch_execute_success() (gas: 26558) KillSwitchValidatorTest:test_external_call_default() (gas: 29426) @@ -84,19 +84,19 @@ KillSwitchValidatorTest:test_external_call_execute_delegatecall_option_fail() (g KillSwitchValidatorTest:test_external_call_execute_delegatecall_success() (gas: 25709) KillSwitchValidatorTest:test_external_call_execute_fail() (gas: 27961) KillSwitchValidatorTest:test_external_call_execute_success() (gas: 26075) -KillSwitchValidatorTest:test_external_call_execution() (gas: 510974) +KillSwitchValidatorTest:test_external_call_execution() (gas: 510963) KillSwitchValidatorTest:test_fail_validate_not_activate() (gas: 303601) KillSwitchValidatorTest:test_fail_validate_wrongsignature() (gas: 34276) -KillSwitchValidatorTest:test_force_unblock() (gas: 391619) +KillSwitchValidatorTest:test_force_unblock() (gas: 391554) KillSwitchValidatorTest:test_get_nonce() (gas: 25201) KillSwitchValidatorTest:test_get_nonce(uint192) (runs: 1024, μ: 19930, ~: 19930) KillSwitchValidatorTest:test_ignore() (gas: 956) KillSwitchValidatorTest:test_initialize() (gas: 154209) KillSwitchValidatorTest:test_initialize_twice() (gas: 18643) -KillSwitchValidatorTest:test_mode_2() (gas: 312742) -KillSwitchValidatorTest:test_revert_when_mode_disabled() (gas: 201434) -KillSwitchValidatorTest:test_set_default_validator() (gas: 423481) -KillSwitchValidatorTest:test_set_execution() (gas: 468471) +KillSwitchValidatorTest:test_mode_2() (gas: 312699) +KillSwitchValidatorTest:test_revert_when_mode_disabled() (gas: 199184) +KillSwitchValidatorTest:test_set_default_validator() (gas: 423470) +KillSwitchValidatorTest:test_set_execution() (gas: 468460) KillSwitchValidatorTest:test_should_emit_event_on_receive() (gas: 23330) KillSwitchValidatorTest:test_should_fail_with_not_implemented_isValidSignature() (gas: 9236) KillSwitchValidatorTest:test_should_fail_with_not_implemented_isValidSignature(bytes32,bytes) (runs: 1024, μ: 9601, ~: 9556) @@ -106,17 +106,17 @@ KillSwitchValidatorTest:test_should_receive_erc1155() (gas: 701233) KillSwitchValidatorTest:test_should_receive_erc1155_batch() (gas: 728499) KillSwitchValidatorTest:test_should_receive_erc721() (gas: 597790) KillSwitchValidatorTest:test_should_return_address_if_deployed() (gas: 22086) -KillSwitchValidatorTest:test_sudo() (gas: 179596) -KillSwitchValidatorTest:test_sudo_wrongSig() (gas: 115877) +KillSwitchValidatorTest:test_sudo() (gas: 179585) +KillSwitchValidatorTest:test_sudo_wrongSig() (gas: 115866) KillSwitchValidatorTest:test_upgrade() (gas: 21314) -KillSwitchValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28810) -KillSwitchValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30705) +KillSwitchValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28767) +KillSwitchValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30699) KillSwitchValidatorTest:test_validate_signature() (gas: 194579) -SessionKeyValidatorTest:test_default_validator_disable() (gas: 180358) -SessionKeyValidatorTest:test_default_validator_enable() (gas: 187847) -SessionKeyValidatorTest:test_disable_mode() (gas: 182842) +SessionKeyValidatorTest:test_default_validator_disable() (gas: 180347) +SessionKeyValidatorTest:test_default_validator_enable() (gas: 187836) +SessionKeyValidatorTest:test_disable_mode() (gas: 182831) SessionKeyValidatorTest:test_eip712() (gas: 15684) -SessionKeyValidatorTest:test_enable_then_mode_1() (gas: 286170) +SessionKeyValidatorTest:test_enable_then_mode_1() (gas: 286116) SessionKeyValidatorTest:test_external_call_batch_execute_fail() (gas: 29589) SessionKeyValidatorTest:test_external_call_batch_execute_success() (gas: 26536) SessionKeyValidatorTest:test_external_call_default() (gas: 29338) @@ -125,7 +125,7 @@ SessionKeyValidatorTest:test_external_call_execute_delegatecall_option_fail() (g SessionKeyValidatorTest:test_external_call_execute_delegatecall_success() (gas: 25621) SessionKeyValidatorTest:test_external_call_execute_fail() (gas: 27917) SessionKeyValidatorTest:test_external_call_execute_success() (gas: 26009) -SessionKeyValidatorTest:test_external_call_execution() (gas: 510875) +SessionKeyValidatorTest:test_external_call_execution() (gas: 510864) SessionKeyValidatorTest:test_fail_validate_not_activate() (gas: 303513) SessionKeyValidatorTest:test_fail_validate_wrongsignature() (gas: 34165) SessionKeyValidatorTest:test_get_nonce() (gas: 25179) @@ -133,22 +133,22 @@ SessionKeyValidatorTest:test_get_nonce(uint192) (runs: 1024, μ: 19842, ~: 19842 SessionKeyValidatorTest:test_ignore() (gas: 890) SessionKeyValidatorTest:test_initialize() (gas: 154121) SessionKeyValidatorTest:test_initialize_twice() (gas: 18555) -SessionKeyValidatorTest:test_mode_2() (gas: 250279) -SessionKeyValidatorTest:test_revert_when_mode_disabled() (gas: 201280) -SessionKeyValidatorTest:test_scenario_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool),(uint8)) (runs: 1024, μ: 43221909, ~: 31867213) -SessionKeyValidatorTest:test_scenario_non_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool)) (runs: 1024, μ: 17443341, ~: 16183886) -SessionKeyValidatorTest:test_set_default_validator() (gas: 423382) -SessionKeyValidatorTest:test_set_execution() (gas: 468350) +SessionKeyValidatorTest:test_mode_2() (gas: 250236) +SessionKeyValidatorTest:test_revert_when_mode_disabled() (gas: 199030) +SessionKeyValidatorTest:test_scenario_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool),(uint8)) (runs: 1024, μ: 43079949, ~: 31812220) +SessionKeyValidatorTest:test_scenario_non_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool)) (runs: 1024, μ: 17488714, ~: 16835616) +SessionKeyValidatorTest:test_set_default_validator() (gas: 423371) +SessionKeyValidatorTest:test_set_execution() (gas: 468339) SessionKeyValidatorTest:test_should_emit_event_on_receive() (gas: 23242) SessionKeyValidatorTest:test_should_receive_erc1155() (gas: 701145) SessionKeyValidatorTest:test_should_receive_erc1155_batch() (gas: 728411) SessionKeyValidatorTest:test_should_receive_erc721() (gas: 597724) SessionKeyValidatorTest:test_should_return_address_if_deployed() (gas: 22003) -SessionKeyValidatorTest:test_sudo() (gas: 179497) -SessionKeyValidatorTest:test_sudo_wrongSig() (gas: 115778) +SessionKeyValidatorTest:test_sudo() (gas: 179486) +SessionKeyValidatorTest:test_sudo_wrongSig() (gas: 115767) SessionKeyValidatorTest:test_upgrade() (gas: 21292) -SessionKeyValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28746) -SessionKeyValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30631) +SessionKeyValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28703) +SessionKeyValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30625) SessionKeyValidatorTest:test_validate_signature() (gas: 194502) TestCallee:test_ignore() (gas: 206) TestCounter:test_ignore() (gas: 164) diff --git a/src/Kernel.sol b/src/Kernel.sol index ffbf975e..88f7d17a 100644 --- a/src/Kernel.sol +++ b/src/Kernel.sol @@ -26,8 +26,12 @@ import {ValidationData, ValidAfter, ValidUntil, parseValidationData, packValidat /// @author taek /// @notice wallet kernel for extensible wallet functionality contract Kernel is EIP712, Compatibility, KernelStorage { - string public constant name = KERNEL_NAME; + /// @dev Selector of the `DisabledMode()` error, to be used in assembly, 'bytes4(keccak256(bytes("DisabledMode()")))', same as DisabledMode.selector() + uint256 private constant _DISABLED_MODE_SELECTOR = 0xfc2f51c5; + + /// @dev Current kernel name and version + string public constant name = KERNEL_NAME; string public constant version = KERNEL_VERSION; /// @dev Sets up the EIP712 and KernelStorage with the provided entry point @@ -133,7 +137,9 @@ contract Kernel is EIP712, Compatibility, KernelStorage { bytes calldata userOpSignature; uint256 userOpEndOffset; assembly { + // Store the userOpSignature offset userOpEndOffset := add(calldataload(0x04), 0x24) + // Extract the user op signature from the calldata (but keep it in the calldata, just extract offset & length) userOpSignature.offset := add(calldataload(add(userOpEndOffset, 0x120)), userOpEndOffset) userOpSignature.length := calldataload(sub(userOpSignature.offset, 0x20)) } @@ -141,7 +147,6 @@ contract Kernel is EIP712, Compatibility, KernelStorage { bytes4 mode = bytes4(userOpSignature[0:4]); // mode == 00..00 use validators // mode == 0x00000000 use sudo validator if (mode == 0x00000000) { - // sudo mode (use default validator) if (missingAccountFunds != 0) { assembly { pop(call(gas(), caller(), missingAccountFunds, callvalue(), callvalue(), callvalue(), callvalue())) @@ -152,19 +157,26 @@ contract Kernel is EIP712, Compatibility, KernelStorage { return _validateUserOp(_userOp, userOpHash, missingAccountFunds); } + // Check if the kernel is disabled, if that's the case, it's only accepting userOperation with sudo mode + assembly ("memory-safe") { + // Extract the disabled mode from the storage slot + let isKernelDisabled := shl(224, sload(KERNEL_STORAGE_SLOT_1)) + // If we got a non-zero disabled mode, and non zero mode, then revert + if and(isKernelDisabled, mode) { + mstore(0x00, _DISABLED_MODE_SELECTOR) + revert(0x1c, 0x04) + } + } + + // Replicate the userOp from memory to calldat UserOperation memory userOp = _userOp; + // The validator that will be used + IKernelValidator validator; + // mode == 0x00000001 use given validator // mode == 0x00000002 enable validator - IKernelValidator validator; - bytes32 storage_slot_1; - assembly { - // sslot 1 contain default validator, disabled mode & disabled date - storage_slot_1 := sload(KERNEL_STORAGE_SLOT_1) - } - if (mode & (storage_slot_1 << 224) != 0x00000000) { - revert DisabledMode(); - } else if (mode == 0x00000001) { + if (mode == 0x00000001) { bytes calldata userOpCallData; assembly { userOpCallData.offset := add(calldataload(add(userOpEndOffset, 0x40)), userOpEndOffset) @@ -189,6 +201,7 @@ contract Kernel is EIP712, Compatibility, KernelStorage { } else { return SIG_VALIDATION_FAILED; } + if (missingAccountFunds != 0) { assembly { pop(call(gas(), caller(), missingAccountFunds, callvalue(), callvalue(), callvalue(), callvalue())) diff --git a/src/common/Constants.sol b/src/common/Constants.sol index 35bf3408..04ec5e19 100644 --- a/src/common/Constants.sol +++ b/src/common/Constants.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import {ValidationData} from "./Types.sol"; -// constants for kernel metadata +// Constants for kernel metadata string constant KERNEL_NAME = "Kernel"; string constant KERNEL_VERSION = "0.2.3"; From e5d70cdda6fe9f57eab2dada472a98f6d26aa18c Mon Sep 17 00:00:00 2001 From: KONFeature Date: Sat, 25 Nov 2023 23:17:58 +0100 Subject: [PATCH 3/4] Missing funds check gas improvments --- src/Kernel.sol | 33 +++++++++++++++++++++------------ src/common/Constants.sol | 4 ++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/Kernel.sol b/src/Kernel.sol index 88f7d17a..de3660dc 100644 --- a/src/Kernel.sol +++ b/src/Kernel.sol @@ -26,7 +26,6 @@ import {ValidationData, ValidAfter, ValidUntil, parseValidationData, packValidat /// @author taek /// @notice wallet kernel for extensible wallet functionality contract Kernel is EIP712, Compatibility, KernelStorage { - /// @dev Selector of the `DisabledMode()` error, to be used in assembly, 'bytes4(keccak256(bytes("DisabledMode()")))', same as DisabledMode.selector() uint256 private constant _DISABLED_MODE_SELECTOR = 0xfc2f51c5; @@ -147,11 +146,11 @@ contract Kernel is EIP712, Compatibility, KernelStorage { bytes4 mode = bytes4(userOpSignature[0:4]); // mode == 00..00 use validators // mode == 0x00000000 use sudo validator if (mode == 0x00000000) { - if (missingAccountFunds != 0) { - assembly { + assembly { + if missingAccountFunds { pop(call(gas(), caller(), missingAccountFunds, callvalue(), callvalue(), callvalue(), callvalue())) + //ignore failure (its EntryPoint's job to verify, not account.) } - //ignore failure (its EntryPoint's job to verify, not account.) } // short circuit here for default validator return _validateUserOp(_userOp, userOpHash, missingAccountFunds); @@ -168,9 +167,6 @@ contract Kernel is EIP712, Compatibility, KernelStorage { } } - // Replicate the userOp from memory to calldat - UserOperation memory userOp = _userOp; - // The validator that will be used IKernelValidator validator; @@ -202,13 +198,18 @@ contract Kernel is EIP712, Compatibility, KernelStorage { return SIG_VALIDATION_FAILED; } - if (missingAccountFunds != 0) { - assembly { + assembly { + if missingAccountFunds { pop(call(gas(), caller(), missingAccountFunds, callvalue(), callvalue(), callvalue(), callvalue())) + //ignore failure (its EntryPoint's job to verify, not account.) } - //ignore failure (its EntryPoint's job to verify, not account.) } + + // Replicate the userOp from memory to calldata, to update it's signature (since with mode 1 & 2 the signatre can be updated) + UserOperation memory userOp = _userOp; userOp.signature = userOpSignature; + + // Get the validator data from the designated signer validationData = _intersectValidationData(validationData, validator.validateUserOp(userOp, userOpHash, missingAccountFunds)); return validationData; @@ -329,14 +330,21 @@ contract Kernel is EIP712, Compatibility, KernelStorage { } } + /// @dev This function will validate user operation and be called by EntryPoint + /// @param _op The user operation to be validated + /// @param _opHash The hash of the user operation + /// @param _missingFunds The funds needed to be reimbursed function _validateUserOp(UserOperation calldata _op, bytes32 _opHash, uint256 _missingFunds) internal virtual returns (ValidationData) { - address validator; + // Replace the user op in memory to update the signature UserOperation memory op = _op; - op.signature = _op.signature[4:]; // since this is only called on default validator + // Remove the validation mode flag from the signature + op.signature = _op.signature[4:]; + + address validator; assembly { validator := shr(80, sload(KERNEL_STORAGE_SLOT_1)) } @@ -359,6 +367,7 @@ contract Kernel is EIP712, Compatibility, KernelStorage { function _validCaller(address _caller, bytes calldata _data) internal view virtual returns (bool) { address validator; assembly { + // Load the validator from the storage slot validator := shr(80, sload(KERNEL_STORAGE_SLOT_1)) } return IKernelValidator(validator).validCaller(_caller, _data); diff --git a/src/common/Constants.sol b/src/common/Constants.sol index 04ec5e19..5568f091 100644 --- a/src/common/Constants.sol +++ b/src/common/Constants.sol @@ -18,8 +18,8 @@ bytes32 constant VALIDATOR_APPROVED_STRUCT_HASH = 0x3ce406685c1b3551d706d85a68af /* -------------------------------------------------------------------------- */ /// @dev Storage slot for the kernel storage -bytes32 constant KERNEL_STORAGE_SLOT = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd8; +bytes32 constant KERNEL_STORAGE_SLOT = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd8; /// @dev Storage pointer inside the kernel storage, with 1 offset, to access directly disblaedMode, disabled date and default validator -bytes32 constant KERNEL_STORAGE_SLOT_1 = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd9; +bytes32 constant KERNEL_STORAGE_SLOT_1 = 0x439ffe7df606b78489639bc0b827913bd09e1246fa6802968a5b3694c53e0dd9; /// @dev Storage slot for the logic implementation address bytes32 constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; From d22e0561344905d2b867872b356a73ccbb2cf7f2 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Sun, 26 Nov 2023 00:08:48 +0100 Subject: [PATCH 4/4] Adding a bit of comments --- .gas-snapshot | 126 +++++++++++++++++------------------ src/Kernel.sol | 30 +++++++-- src/common/Constants.sol | 2 + src/lite/KernelLiteECDSA.sol | 9 +++ 4 files changed, 98 insertions(+), 69 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 0b3aff9c..e41656f8 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,31 +1,31 @@ KernelECDSATest:test_default_validator_disable() (gas: 0) -KernelECDSATest:test_default_validator_disable() (gas: 180304) +KernelECDSATest:test_default_validator_disable() (gas: 180311) KernelECDSATest:test_default_validator_enable() (gas: 0) -KernelECDSATest:test_default_validator_enable() (gas: 187793) -KernelECDSATest:test_disable_mode() (gas: 182788) -KernelECDSATest:test_disable_mode() (gas: 192110) +KernelECDSATest:test_default_validator_enable() (gas: 187800) +KernelECDSATest:test_disable_mode() (gas: 182795) +KernelECDSATest:test_disable_mode() (gas: 192079) KernelECDSATest:test_eip712() (gas: 15684) KernelECDSATest:test_eip712() (gas: 15684) -KernelECDSATest:test_enable_then_mode_1() (gas: 277977) -KernelECDSATest:test_enable_then_mode_1() (gas: 286051) +KernelECDSATest:test_enable_then_mode_1() (gas: 277994) +KernelECDSATest:test_enable_then_mode_1() (gas: 286106) KernelECDSATest:test_external_call_batch_execute_fail() (gas: 23628) -KernelECDSATest:test_external_call_batch_execute_fail() (gas: 29589) +KernelECDSATest:test_external_call_batch_execute_fail() (gas: 29534) KernelECDSATest:test_external_call_batch_execute_success() (gas: 20629) KernelECDSATest:test_external_call_batch_execute_success() (gas: 26536) KernelECDSATest:test_external_call_default() (gas: 23511) KernelECDSATest:test_external_call_default() (gas: 29338) KernelECDSATest:test_external_call_execute_delegatecall_fail() (gas: 22499) -KernelECDSATest:test_external_call_execute_delegatecall_fail() (gas: 28436) +KernelECDSATest:test_external_call_execute_delegatecall_fail() (gas: 28381) KernelECDSATest:test_external_call_execute_delegatecall_option_fail() (gas: 20434) KernelECDSATest:test_external_call_execute_delegatecall_option_fail() (gas: 26329) KernelECDSATest:test_external_call_execute_delegatecall_success() (gas: 19738) KernelECDSATest:test_external_call_execute_delegatecall_success() (gas: 25621) KernelECDSATest:test_external_call_execute_fail() (gas: 21968) -KernelECDSATest:test_external_call_execute_fail() (gas: 27917) +KernelECDSATest:test_external_call_execute_fail() (gas: 27862) KernelECDSATest:test_external_call_execute_success() (gas: 20070) KernelECDSATest:test_external_call_execute_success() (gas: 25987) -KernelECDSATest:test_external_call_execution() (gas: 497850) -KernelECDSATest:test_external_call_execution() (gas: 510799) +KernelECDSATest:test_external_call_execution() (gas: 497819) +KernelECDSATest:test_external_call_execution() (gas: 510696) KernelECDSATest:test_fail_validate_not_activate() (gas: 0) KernelECDSATest:test_fail_validate_not_activate() (gas: 303491) KernelECDSATest:test_fail_validate_wrongsignature() (gas: 24904) @@ -39,14 +39,14 @@ KernelECDSATest:test_initialize() (gas: 126784) KernelECDSATest:test_initialize() (gas: 154121) KernelECDSATest:test_initialize_twice() (gas: 18555) KernelECDSATest:test_initialize_twice() (gas: 18698) -KernelECDSATest:test_mode_2() (gas: 242990) -KernelECDSATest:test_mode_2() (gas: 250181) -KernelECDSATest:test_revert_when_mode_disabled() (gas: 198987) -KernelECDSATest:test_revert_when_mode_disabled() (gas: 208309) -KernelECDSATest:test_set_default_validator() (gas: 417176) -KernelECDSATest:test_set_default_validator() (gas: 423328) -KernelECDSATest:test_set_execution() (gas: 458173) -KernelECDSATest:test_set_execution() (gas: 468296) +KernelECDSATest:test_mode_2() (gas: 243052) +KernelECDSATest:test_mode_2() (gas: 250243) +KernelECDSATest:test_revert_when_mode_disabled() (gas: 199003) +KernelECDSATest:test_revert_when_mode_disabled() (gas: 208287) +KernelECDSATest:test_set_default_validator() (gas: 417145) +KernelECDSATest:test_set_default_validator() (gas: 423335) +KernelECDSATest:test_set_execution() (gas: 458142) +KernelECDSATest:test_set_execution() (gas: 468303) KernelECDSATest:test_should_emit_event_on_receive() (gas: 23220) KernelECDSATest:test_should_emit_event_on_receive() (gas: 23220) KernelECDSATest:test_should_receive_erc1155() (gas: 701145) @@ -57,46 +57,46 @@ KernelECDSATest:test_should_receive_erc721() (gas: 597680) KernelECDSATest:test_should_receive_erc721() (gas: 597702) KernelECDSATest:test_should_return_address_if_deployed() (gas: 21970) KernelECDSATest:test_should_return_address_if_deployed() (gas: 21976) -KernelECDSATest:test_sudo() (gas: 170033) -KernelECDSATest:test_sudo() (gas: 179443) -KernelECDSATest:test_sudo_wrongSig() (gas: 102554) -KernelECDSATest:test_sudo_wrongSig() (gas: 115745) -KernelECDSATest:test_transfer_ownership() (gas: 178429) +KernelECDSATest:test_sudo() (gas: 170002) +KernelECDSATest:test_sudo() (gas: 179450) +KernelECDSATest:test_sudo_wrongSig() (gas: 102566) +KernelECDSATest:test_sudo_wrongSig() (gas: 115709) +KernelECDSATest:test_transfer_ownership() (gas: 178398) KernelECDSATest:test_upgrade() (gas: 21292) KernelECDSATest:test_upgrade() (gas: 21292) -KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28679) -KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 28679) -KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30582) -KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30625) +KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 26550) +KernelECDSATest:test_validateUserOp_fail_invalid_mode() (gas: 26550) +KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30591) +KernelECDSATest:test_validateUserOp_fail_not_entryPoint() (gas: 30634) KernelECDSATest:test_validate_signature() (gas: 155714) KernelECDSATest:test_validate_signature() (gas: 194502) KernelHelperTest:testIntersect(uint48,uint48,uint48,uint48) (runs: 1024, μ: 871, ~: 869) -KillSwitchValidatorTest:test_default_validator_disable() (gas: 180468) -KillSwitchValidatorTest:test_default_validator_enable() (gas: 187957) -KillSwitchValidatorTest:test_disable_mode() (gas: 182952) +KillSwitchValidatorTest:test_default_validator_disable() (gas: 180432) +KillSwitchValidatorTest:test_default_validator_enable() (gas: 187921) +KillSwitchValidatorTest:test_disable_mode() (gas: 182916) KillSwitchValidatorTest:test_eip712() (gas: 15820) -KillSwitchValidatorTest:test_enable_then_mode_1() (gas: 348574) -KillSwitchValidatorTest:test_external_call_batch_execute_fail() (gas: 29677) +KillSwitchValidatorTest:test_enable_then_mode_1() (gas: 348586) +KillSwitchValidatorTest:test_external_call_batch_execute_fail() (gas: 29622) KillSwitchValidatorTest:test_external_call_batch_execute_success() (gas: 26558) KillSwitchValidatorTest:test_external_call_default() (gas: 29426) -KillSwitchValidatorTest:test_external_call_execute_delegatecall_fail() (gas: 28524) +KillSwitchValidatorTest:test_external_call_execute_delegatecall_fail() (gas: 28469) KillSwitchValidatorTest:test_external_call_execute_delegatecall_option_fail() (gas: 26439) KillSwitchValidatorTest:test_external_call_execute_delegatecall_success() (gas: 25709) -KillSwitchValidatorTest:test_external_call_execute_fail() (gas: 27961) +KillSwitchValidatorTest:test_external_call_execute_fail() (gas: 27906) KillSwitchValidatorTest:test_external_call_execute_success() (gas: 26075) -KillSwitchValidatorTest:test_external_call_execution() (gas: 510963) +KillSwitchValidatorTest:test_external_call_execution() (gas: 510817) KillSwitchValidatorTest:test_fail_validate_not_activate() (gas: 303601) KillSwitchValidatorTest:test_fail_validate_wrongsignature() (gas: 34276) -KillSwitchValidatorTest:test_force_unblock() (gas: 391554) +KillSwitchValidatorTest:test_force_unblock() (gas: 391544) KillSwitchValidatorTest:test_get_nonce() (gas: 25201) KillSwitchValidatorTest:test_get_nonce(uint192) (runs: 1024, μ: 19930, ~: 19930) KillSwitchValidatorTest:test_ignore() (gas: 956) KillSwitchValidatorTest:test_initialize() (gas: 154209) KillSwitchValidatorTest:test_initialize_twice() (gas: 18643) -KillSwitchValidatorTest:test_mode_2() (gas: 312699) -KillSwitchValidatorTest:test_revert_when_mode_disabled() (gas: 199184) -KillSwitchValidatorTest:test_set_default_validator() (gas: 423470) -KillSwitchValidatorTest:test_set_execution() (gas: 468460) +KillSwitchValidatorTest:test_mode_2() (gas: 312761) +KillSwitchValidatorTest:test_revert_when_mode_disabled() (gas: 199157) +KillSwitchValidatorTest:test_set_default_validator() (gas: 423434) +KillSwitchValidatorTest:test_set_execution() (gas: 468424) KillSwitchValidatorTest:test_should_emit_event_on_receive() (gas: 23330) KillSwitchValidatorTest:test_should_fail_with_not_implemented_isValidSignature() (gas: 9236) KillSwitchValidatorTest:test_should_fail_with_not_implemented_isValidSignature(bytes32,bytes) (runs: 1024, μ: 9601, ~: 9556) @@ -106,26 +106,26 @@ KillSwitchValidatorTest:test_should_receive_erc1155() (gas: 701233) KillSwitchValidatorTest:test_should_receive_erc1155_batch() (gas: 728499) KillSwitchValidatorTest:test_should_receive_erc721() (gas: 597790) KillSwitchValidatorTest:test_should_return_address_if_deployed() (gas: 22086) -KillSwitchValidatorTest:test_sudo() (gas: 179585) -KillSwitchValidatorTest:test_sudo_wrongSig() (gas: 115866) +KillSwitchValidatorTest:test_sudo() (gas: 179549) +KillSwitchValidatorTest:test_sudo_wrongSig() (gas: 115830) KillSwitchValidatorTest:test_upgrade() (gas: 21314) -KillSwitchValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28767) -KillSwitchValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30699) +KillSwitchValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 26638) +KillSwitchValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30708) KillSwitchValidatorTest:test_validate_signature() (gas: 194579) -SessionKeyValidatorTest:test_default_validator_disable() (gas: 180347) -SessionKeyValidatorTest:test_default_validator_enable() (gas: 187836) -SessionKeyValidatorTest:test_disable_mode() (gas: 182831) +SessionKeyValidatorTest:test_default_validator_disable() (gas: 180311) +SessionKeyValidatorTest:test_default_validator_enable() (gas: 187800) +SessionKeyValidatorTest:test_disable_mode() (gas: 182795) SessionKeyValidatorTest:test_eip712() (gas: 15684) -SessionKeyValidatorTest:test_enable_then_mode_1() (gas: 286116) -SessionKeyValidatorTest:test_external_call_batch_execute_fail() (gas: 29589) +SessionKeyValidatorTest:test_enable_then_mode_1() (gas: 286128) +SessionKeyValidatorTest:test_external_call_batch_execute_fail() (gas: 29534) SessionKeyValidatorTest:test_external_call_batch_execute_success() (gas: 26536) SessionKeyValidatorTest:test_external_call_default() (gas: 29338) -SessionKeyValidatorTest:test_external_call_execute_delegatecall_fail() (gas: 28436) +SessionKeyValidatorTest:test_external_call_execute_delegatecall_fail() (gas: 28381) SessionKeyValidatorTest:test_external_call_execute_delegatecall_option_fail() (gas: 26351) SessionKeyValidatorTest:test_external_call_execute_delegatecall_success() (gas: 25621) -SessionKeyValidatorTest:test_external_call_execute_fail() (gas: 27917) +SessionKeyValidatorTest:test_external_call_execute_fail() (gas: 27862) SessionKeyValidatorTest:test_external_call_execute_success() (gas: 26009) -SessionKeyValidatorTest:test_external_call_execution() (gas: 510864) +SessionKeyValidatorTest:test_external_call_execution() (gas: 510718) SessionKeyValidatorTest:test_fail_validate_not_activate() (gas: 303513) SessionKeyValidatorTest:test_fail_validate_wrongsignature() (gas: 34165) SessionKeyValidatorTest:test_get_nonce() (gas: 25179) @@ -133,22 +133,22 @@ SessionKeyValidatorTest:test_get_nonce(uint192) (runs: 1024, μ: 19842, ~: 19842 SessionKeyValidatorTest:test_ignore() (gas: 890) SessionKeyValidatorTest:test_initialize() (gas: 154121) SessionKeyValidatorTest:test_initialize_twice() (gas: 18555) -SessionKeyValidatorTest:test_mode_2() (gas: 250236) -SessionKeyValidatorTest:test_revert_when_mode_disabled() (gas: 199030) -SessionKeyValidatorTest:test_scenario_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool),(uint8)) (runs: 1024, μ: 43079949, ~: 31812220) -SessionKeyValidatorTest:test_scenario_non_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool)) (runs: 1024, μ: 17488714, ~: 16835616) -SessionKeyValidatorTest:test_set_default_validator() (gas: 423371) -SessionKeyValidatorTest:test_set_execution() (gas: 468339) +SessionKeyValidatorTest:test_mode_2() (gas: 250298) +SessionKeyValidatorTest:test_revert_when_mode_disabled() (gas: 199003) +SessionKeyValidatorTest:test_scenario_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool),(uint8)) (runs: 1024, μ: 43997409, ~: 32002162) +SessionKeyValidatorTest:test_scenario_non_batch((uint8,uint8,uint8,uint8,uint48,uint48,uint48,uint48,bool,bool,bool,bool)) (runs: 1024, μ: 17511495, ~: 17372686) +SessionKeyValidatorTest:test_set_default_validator() (gas: 423335) +SessionKeyValidatorTest:test_set_execution() (gas: 468303) SessionKeyValidatorTest:test_should_emit_event_on_receive() (gas: 23242) SessionKeyValidatorTest:test_should_receive_erc1155() (gas: 701145) SessionKeyValidatorTest:test_should_receive_erc1155_batch() (gas: 728411) SessionKeyValidatorTest:test_should_receive_erc721() (gas: 597724) SessionKeyValidatorTest:test_should_return_address_if_deployed() (gas: 22003) -SessionKeyValidatorTest:test_sudo() (gas: 179486) -SessionKeyValidatorTest:test_sudo_wrongSig() (gas: 115767) +SessionKeyValidatorTest:test_sudo() (gas: 179450) +SessionKeyValidatorTest:test_sudo_wrongSig() (gas: 115731) SessionKeyValidatorTest:test_upgrade() (gas: 21292) -SessionKeyValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 28703) -SessionKeyValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30625) +SessionKeyValidatorTest:test_validateUserOp_fail_invalid_mode() (gas: 26574) +SessionKeyValidatorTest:test_validateUserOp_fail_not_entryPoint() (gas: 30634) SessionKeyValidatorTest:test_validate_signature() (gas: 194502) TestCallee:test_ignore() (gas: 206) TestCounter:test_ignore() (gas: 164) diff --git a/src/Kernel.sol b/src/Kernel.sol index de3660dc..74f2425b 100644 --- a/src/Kernel.sol +++ b/src/Kernel.sol @@ -29,17 +29,13 @@ contract Kernel is EIP712, Compatibility, KernelStorage { /// @dev Selector of the `DisabledMode()` error, to be used in assembly, 'bytes4(keccak256(bytes("DisabledMode()")))', same as DisabledMode.selector() uint256 private constant _DISABLED_MODE_SELECTOR = 0xfc2f51c5; - /// @dev Current kernel name and version + /// @dev Current kernel name and version, todo: Need to expose getter for this variables? string public constant name = KERNEL_NAME; string public constant version = KERNEL_VERSION; /// @dev Sets up the EIP712 and KernelStorage with the provided entry point constructor(IEntryPoint _entryPoint) KernelStorage(_entryPoint) {} - function _domainNameAndVersion() internal pure override returns (string memory, string memory) { - return (name, version); - } - /// @notice Accepts incoming Ether transactions and calls from the EntryPoint contract /// @dev This function will delegate any call to the appropriate executor based on the function signature. fallback() external payable { @@ -215,6 +211,9 @@ contract Kernel is EIP712, Compatibility, KernelStorage { return validationData; } + /// @dev This function will approve a new validator for the current kernel + /// @param sig The signature of the userOp asking for a validator approval + /// @param signature The signature of the userOp asking for a validator approval function _approveValidator(bytes4 sig, bytes calldata signature) internal returns (IKernelValidator validator, ValidationData validationData, bytes calldata validationSig) @@ -266,10 +265,19 @@ contract Kernel is EIP712, Compatibility, KernelStorage { } } + /// @dev Validates a signature for the given kernel + /// @param hash The hash of the data that was signed + /// @param signature The signature to be validated function validateSignature(bytes32 hash, bytes calldata signature) public view returns (ValidationData) { return _validateSignature(hash, signature); } + /// @dev Get the current name & version of the kernel, used for the EIP-712 domain separator + function _domainNameAndVersion() internal pure override returns (string memory, string memory) { + return (name, version); + } + + /// @dev Get an EIP-712 compliant domain separator function _domainSeparator() internal view override returns (bytes32) { // Obtain the name and version from the _domainNameAndVersion function. (string memory _name, string memory _version) = _domainNameAndVersion(); @@ -313,6 +321,8 @@ contract Kernel is EIP712, Compatibility, KernelStorage { } } + /// @dev Check if the current caller is authorized or no to perform the call + /// @return True if the caller is authorized, otherwise false function _checkCaller() internal view returns (bool) { if (_validCaller(msg.sender, msg.data)) { return true; @@ -344,13 +354,17 @@ contract Kernel is EIP712, Compatibility, KernelStorage { // Remove the validation mode flag from the signature op.signature = _op.signature[4:]; - address validator; + IKernelValidator validator; assembly { validator := shr(80, sload(KERNEL_STORAGE_SLOT_1)) } return IKernelValidator(validator).validateUserOp(op, _opHash, _missingFunds); } + /// @dev This function will validate a signature for the given kernel + /// @param _hash The hash of the data that was signed + /// @param _signature The signature to be validated + /// @return The magic value 0x1626ba7e if the signature is valid, otherwise returns 0xffffffff. function _validateSignature(bytes32 _hash, bytes calldata _signature) internal view @@ -364,6 +378,10 @@ contract Kernel is EIP712, Compatibility, KernelStorage { return IKernelValidator(validator).validateSignature(_hash, _signature); } + /// @dev Check if the given caller is valid for the given data + /// @param _caller The caller to be checked + /// @param _data The data to be checked + /// @return True if the caller is valid, otherwise false function _validCaller(address _caller, bytes calldata _data) internal view virtual returns (bool) { address validator; assembly { diff --git a/src/common/Constants.sol b/src/common/Constants.sol index 5568f091..b69cb162 100644 --- a/src/common/Constants.sol +++ b/src/common/Constants.sol @@ -11,6 +11,8 @@ uint256 constant SIG_VALIDATION_FAILED_UINT = 1; ValidationData constant SIG_VALIDATION_FAILED = ValidationData.wrap(SIG_VALIDATION_FAILED_UINT); // STRUCT_HASH + +/// @dev Struct hash for the ValidatorApproved struct -> keccak256("ValidatorApproved(bytes4 sig,uint256 validatorData,address executor,bytes enableData)") bytes32 constant VALIDATOR_APPROVED_STRUCT_HASH = 0x3ce406685c1b3551d706d85a68afdaa49ac4e07b451ad9b8ff8b58c3ee964176; /* -------------------------------------------------------------------------- */ diff --git a/src/lite/KernelLiteECDSA.sol b/src/lite/KernelLiteECDSA.sol index ab7a73f1..a483d63d 100644 --- a/src/lite/KernelLiteECDSA.sol +++ b/src/lite/KernelLiteECDSA.sol @@ -15,10 +15,14 @@ struct KernelLiteECDSAStorage { address owner; } +/// @title KernelLiteECDSA Contract +/// @dev A lite version of the Kernel contract which only uses ECDSA signatures for validation contract KernelLiteECDSA is Kernel { error InvalidAccess(); address public immutable KERNEL_ECDSA_VALIDATOR; + + /// @dev The storage slot for this contract bytes32 private constant KERNEL_LITE_ECDSA_STORAGE_SLOT = 0xdea7fea882fba743201b2aeb1babf326b8944488db560784858525d123ee7e97; // keccak256(abi.encodePacked("zerodev.kernel.lite.ecdsa")) - 1 @@ -27,6 +31,7 @@ contract KernelLiteECDSA is Kernel { getKernelLiteECDSAStorage().owner = address(1); // set owner to non-zero address to prevent initialization } + /// @dev Transfer the ownership of this current kernel function transferOwnership(address _newOwner) external payable onlyFromEntryPointOrSelf { getKernelLiteECDSAStorage().owner = _newOwner; } @@ -38,6 +43,7 @@ contract KernelLiteECDSA is Kernel { } } + /// @dev Set the initial data for this kernel (setup ecdsa signer address) function _setInitialData(IKernelValidator _validator, bytes calldata _data) internal override { require(address(_validator) == KERNEL_ECDSA_VALIDATOR, "KernelLiteECDSA: invalid validator"); require(getKernelLiteECDSAStorage().owner == address(0), "KernelLiteECDSA: already initialized"); @@ -45,6 +51,7 @@ contract KernelLiteECDSA is Kernel { getKernelLiteECDSAStorage().owner = owner; } + /// @dev Validate a user operation function _validateUserOp(UserOperation calldata _op, bytes32 _opHash, uint256) internal view @@ -58,6 +65,7 @@ contract KernelLiteECDSA is Kernel { return ValidationData.wrap(0); } + /// @dev Validate a signature function _validateSignature(bytes32 _hash, bytes calldata _signature) internal view @@ -71,6 +79,7 @@ contract KernelLiteECDSA is Kernel { return SIG_VALIDATION_FAILED; } + /// @dev Check if the caller is valid function _validCaller(address _caller, bytes calldata) internal view override returns (bool) { return _caller == getKernelLiteECDSAStorage().owner; }