diff --git a/package.json b/package.json index fe428eb5..8019e21e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@zerodevapp/contracts", "description": "ZeroDev Account Abstraction (EIP 4337) contracts", "main": "./dist/index.js", - "version": "4.0.0-beta.13", + "version": "4.0.0-beta.14", "scripts": { "prepack": "./scripts/prepack-contracts-package.sh", "postpack": "./scripts/postpack-contracts-package.sh" diff --git a/src/executor/KillSwitchAction.sol b/src/executor/KillSwitchAction.sol index 6a0f455b..0d8a633d 100644 --- a/src/executor/KillSwitchAction.sol +++ b/src/executor/KillSwitchAction.sol @@ -1,10 +1,13 @@ +pragma solidity ^0.8.18; + import "src/validator/IValidator.sol"; +import "src/validator/KillSwitchValidator.sol"; import "src/abstract/KernelStorage.sol"; contract KillSwitchAction { - IKernelValidator public immutable killSwitchValidator; + KillSwitchValidator public immutable killSwitchValidator; - constructor(IKernelValidator _killswitchValidator) { + constructor(KillSwitchValidator _killswitchValidator) { killSwitchValidator = _killswitchValidator; } @@ -16,10 +19,18 @@ contract KillSwitchAction { } } - function activateKillSwitch() external { + function toggleKillSwitch() external { WalletKernelStorage storage ws = getKernelStorage(); - ws.defaultValidator = killSwitchValidator; - getKernelStorage().disabledMode = bytes4(0xffffffff); - getKernelStorage().lastDisabledTime = uint48(block.timestamp); + if(address(ws.defaultValidator) != address(killSwitchValidator)) { + // this means it is not activated + ws.defaultValidator = killSwitchValidator; + getKernelStorage().disabledMode = bytes4(0xffffffff); + getKernelStorage().lastDisabledTime = uint48(block.timestamp); + } else { + (address guardian, IKernelValidator prevValidator, , bytes4 prevDisableMode) = killSwitchValidator.killSwitchValidatorStorage(address(this)); + // this means it is activated + ws.defaultValidator = prevValidator; + getKernelStorage().disabledMode = prevDisableMode; + } } } diff --git a/src/validator/KillSwitchValidator.sol b/src/validator/KillSwitchValidator.sol index f72f3937..81280311 100644 --- a/src/validator/KillSwitchValidator.sol +++ b/src/validator/KillSwitchValidator.sol @@ -15,6 +15,7 @@ struct KillSwitchValidatorStorage { address guardian; IKernelValidator validator; uint48 pausedUntil; + bytes4 disableMode; } contract KillSwitchValidator is IKernelValidator { @@ -37,6 +38,7 @@ contract KillSwitchValidator is IKernelValidator { uint256 delayedData = _packValidationData(false, 0, pausedUntil); return _packValidationData(_intersectTimeRange(res, delayedData)); } + return SIG_VALIDATION_FAILED; } function validateUserOp(UserOperation calldata _userOp, bytes32 _userOpHash, uint256) @@ -64,6 +66,7 @@ contract KillSwitchValidator is IKernelValidator { // save data to this storage validatorStorage.pausedUntil = uint48(bytes6(_userOp.signature[0:6])); validatorStorage.validator = KernelStorage(msg.sender).getDefaultValidator(); + validatorStorage.disableMode = KernelStorage(msg.sender).getDisabledMode(); bytes32 hash = ECDSA.toEthSignedMessageHash(keccak256(bytes.concat(_userOp.signature[0:6],_userOpHash))); address recovered = ECDSA.recover(hash, _userOp.signature[6:]); if (validatorStorage.guardian != recovered) { diff --git a/test/foundry/KillSwitch.t.sol b/test/foundry/KillSwitch.t.sol index d285afce..eaf632b1 100644 --- a/test/foundry/KillSwitch.t.sol +++ b/test/foundry/KillSwitch.t.sol @@ -57,7 +57,7 @@ contract KernelExecutionTest is Test { op = entryPoint.fillUserOp( address(kernel), - abi.encodeWithSelector(KillSwitchAction.activateKillSwitch.selector) + abi.encodeWithSelector(KillSwitchAction.toggleKillSwitch.selector) ); address guardianKeyAddr; uint256 guardianKeyPriv; @@ -68,7 +68,7 @@ contract KernelExecutionTest is Test { { bytes32 digest = getTypedDataHash( address(kernel), - KillSwitchAction.activateKillSwitch.selector, + KillSwitchAction.toggleKillSwitch.selector, 0, 0, address(killSwitch),