Skip to content

Commit 3cf48a5

Browse files
authored
Feat/session key owned (#6)
* session key owned validator * named variable for mapping * deployed to goerli
1 parent 14c47be commit 3cf48a5

6 files changed

Lines changed: 464 additions & 2 deletions

File tree

broadcast/DeployKernel.s.sol/5/run-1686212610.json

Lines changed: 104 additions & 0 deletions
Large diffs are not rendered by default.

broadcast/DeployKernel.s.sol/5/run-1686212623.json

Lines changed: 149 additions & 0 deletions
Large diffs are not rendered by default.

broadcast/DeployKernel.s.sol/5/run-latest.json

Lines changed: 149 additions & 0 deletions
Large diffs are not rendered by default.

foundry.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ src = 'src'
33
out = 'out'
44
libs = ['lib']
55
remappings = ['account-abstraction/=lib/account-abstraction/contracts/']
6+
solc_version = '0.8.19'
67
bytecode_hash = "none"
78
cbor_metadata = false
89
optimize = true
910
runs = 1000000
1011

11-
# See more config options https://github.com/foundry-rs/foundry/tree/master/config
12+
# See more config options https://github.com/foundry-rs/foundry/tree/master/config

src/validator/KillSwitchValidator.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ contract KillSwitchValidator is IKernelValidator {
4242
address signer;
4343
bytes calldata signature;
4444
KillSwitchValidatorStorage storage validatorStorage = killSwitchValidatorStorage[_userOp.sender];
45-
if (_userOp.signature.length == 6 + 20 + 65) {
45+
if (_userOp.signature.length == 6 + 65) {
4646
require(bytes4(_userOp.callData[0:4]) != KernelStorage.disableMode.selector);
4747
signer = validatorStorage.guardian;
4848
uint48 pausedUntil = uint48(bytes6(_userOp.signature[0:6]));
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.0;
4+
5+
import "./IValidator.sol";
6+
import "openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol";
7+
import "src/utils/KernelHelper.sol";
8+
import "account-abstraction/core/Helpers.sol";
9+
10+
struct SessionKeyStorage {
11+
uint48 validUntil;
12+
uint48 validAfter;
13+
}
14+
15+
contract SessionKeyOwnedValidator is IKernelValidator {
16+
event OwnerChanged(address indexed kernel, address indexed oldOwner, address indexed newOwner);
17+
18+
mapping(address sessionKey => mapping(address kernel => SessionKeyStorage)) public sessionKeyStorage;
19+
20+
function disable(bytes calldata _data) external override {
21+
address sessionKey = address(bytes20(_data[0:20]));
22+
delete sessionKeyStorage[sessionKey][msg.sender];
23+
}
24+
25+
function enable(bytes calldata _data) external override {
26+
address sessionKey = address(bytes20(_data[0:20]));
27+
uint48 validUntil = uint48(bytes6(_data[20:26]));
28+
uint48 validAfter = uint48(bytes6(_data[26:32]));
29+
require(validUntil > validAfter, "SessionKeyOwnedValidator: invalid validUntil/validAfter"); // we do not allow validUntil == 0 here use validUntil == 2**48-1 instead
30+
sessionKeyStorage[sessionKey][msg.sender] = SessionKeyStorage(validUntil, validAfter);
31+
}
32+
33+
function validateUserOp(UserOperation calldata _userOp, bytes32 _userOpHash, uint256)
34+
external
35+
view
36+
override
37+
returns (uint256 validationData)
38+
{
39+
bytes32 hash = ECDSA.toEthSignedMessageHash(_userOpHash);
40+
address recovered = ECDSA.recover(hash, _userOp.signature);
41+
42+
SessionKeyStorage storage sessionKey = sessionKeyStorage[recovered][msg.sender];
43+
if (sessionKey.validUntil == 0 ) { // we do not allow validUntil == 0 here
44+
return SIG_VALIDATION_FAILED;
45+
}
46+
return _packValidationData(false, sessionKey.validUntil, sessionKey.validAfter);
47+
}
48+
49+
function validateSignature(bytes32 hash, bytes calldata signature) public view override returns (uint256) {
50+
bytes32 ethhash = ECDSA.toEthSignedMessageHash(hash);
51+
address recovered = ECDSA.recover(ethhash, signature);
52+
53+
SessionKeyStorage storage sessionKey = sessionKeyStorage[recovered][msg.sender];
54+
if (sessionKey.validUntil == 0 ) { // we do not allow validUntil == 0 here
55+
return SIG_VALIDATION_FAILED;
56+
}
57+
return _packValidationData(false, sessionKey.validUntil, sessionKey.validAfter);
58+
}
59+
}

0 commit comments

Comments
 (0)