forked from zerodevapp/kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SessionKeyOwnedValidator.sol
69 lines (56 loc) · 2.77 KB
/
SessionKeyOwnedValidator.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IValidator.sol";
import "openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol";
import "src/utils/KernelHelper.sol";
import "account-abstraction/core/Helpers.sol";
struct SessionKeyStorage {
uint48 validUntil;
uint48 validAfter;
}
contract SessionKeyOwnedValidator is IKernelValidator {
event OwnerChanged(address indexed kernel, address indexed oldOwner, address indexed newOwner);
mapping(address sessionKey => mapping(address kernel => SessionKeyStorage)) public sessionKeyStorage;
function disable(bytes calldata _data) external override {
address sessionKey = address(bytes20(_data[0:20]));
delete sessionKeyStorage[sessionKey][msg.sender];
}
function enable(bytes calldata _data) external override {
address sessionKey = address(bytes20(_data[0:20]));
uint48 validUntil = uint48(bytes6(_data[20:26]));
uint48 validAfter = uint48(bytes6(_data[26:32]));
require(validUntil > validAfter, "SessionKeyOwnedValidator: invalid validUntil/validAfter"); // we do not allow validUntil == 0 here use validUntil == 2**48-1 instead
sessionKeyStorage[sessionKey][msg.sender] = SessionKeyStorage(validUntil, validAfter);
}
function validateUserOp(UserOperation calldata _userOp, bytes32 _userOpHash, uint256)
external
view
override
returns (uint256 validationData)
{
bytes32 hash = ECDSA.toEthSignedMessageHash(_userOpHash);
address recovered = ECDSA.recover(hash, _userOp.signature);
SessionKeyStorage storage sessionKey = sessionKeyStorage[recovered][msg.sender];
if (sessionKey.validUntil == 0) {
// we do not allow validUntil == 0 for session keys
return SIG_VALIDATION_FAILED;
}
return _packValidationData(false, sessionKey.validUntil, sessionKey.validAfter);
}
function validateSignature(bytes32 hash, bytes calldata signature) public view override returns (uint256) {
address recovered = ECDSA.recover(hash, signature);
SessionKeyStorage storage sessionKey = sessionKeyStorage[recovered][msg.sender];
if (sessionKey.validUntil != 0) {
// we do not allow validUntil == 0 for session keys
return _packValidationData(false, sessionKey.validUntil, sessionKey.validAfter);
}
hash = ECDSA.toEthSignedMessageHash(hash);
recovered = ECDSA.recover(hash, signature);
sessionKey = sessionKeyStorage[recovered][msg.sender];
// we do not allow validUntil == 0 for session keys
if (sessionKey.validUntil != 0) {
return _packValidationData(false, sessionKey.validUntil, sessionKey.validAfter);
}
return SIG_VALIDATION_FAILED;
}
}