Skip to content

Commit 6fdb395

Browse files
authored
change kernel sig order for validUntil and validAfter (#21)
* forge fmt * fix: parsing typo and mode(1)
1 parent 2e27f8b commit 6fdb395

File tree

13 files changed

+91
-85
lines changed

13 files changed

+91
-85
lines changed

gas/ecdsa/report.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ No files changed, compilation skipped
33
Running 8 tests for test/foundry/Kernel.t.sol:KernelTest
44
[PASS] test_disable_mode() (gas: 162901)
55
[PASS] test_external_call_default() (gas: 28867)
6-
[PASS] test_external_call_execution() (gas: 453376)
6+
[PASS] test_external_call_execution() (gas: 453373)
77
[PASS] test_initialize_twice() (gas: 20885)
88
[PASS] test_set_default_validator() (gas: 361374)
9-
[PASS] test_set_execution() (gas: 411711)
9+
[PASS] test_set_execution() (gas: 411708)
1010
[PASS] test_validate_signature() (gas: 163680)
11-
[PASS] test_validate_userOp() (gas: 1729466)
12-
Test result: ok. 8 passed; 0 failed; 0 skipped; finished in 2.82ms
11+
[PASS] test_validate_userOp() (gas: 1727059)
12+
Test result: ok. 8 passed; 0 failed; 0 skipped; finished in 2.90ms
1313
| src/Kernel.sol:Kernel contract | | | | | |
1414
|--------------------------------|-----------------|-------|--------|-------|---------|
1515
| Deployment Cost | Deployment Size | | | | |
16-
| 1586591 | 8333 | | | | |
16+
| 1584184 | 8321 | | | | |
1717
| Function Name | min | avg | median | max | # calls |
1818
| disableMode | 3765 | 3765 | 3765 | 3765 | 1 |
1919
| getDefaultValidator | 341 | 341 | 341 | 341 | 1 |
@@ -22,7 +22,7 @@ Test result: ok. 8 passed; 0 failed; 0 skipped; finished in 2.82ms
2222
| initialize | 3046 | 43982 | 48253 | 50753 | 10 |
2323
| isValidSignature | 6047 | 6047 | 6047 | 6047 | 1 |
2424
| setDefaultValidator | 7870 | 7870 | 7870 | 7870 | 1 |
25-
| setExecution | 49877 | 49877 | 49877 | 49877 | 2 |
25+
| setExecution | 49874 | 49874 | 49874 | 49874 | 2 |
2626
| validateUserOp | 46040 | 46234 | 46256 | 46386 | 4 |
2727

2828

src/Kernel.sol

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
114114
assembly {
115115
validator := shr(80, storage_slot_1)
116116
}
117-
} else if(mode & (storage_slot_1 << 224) != 0x00000000) {
117+
} else if (mode & (storage_slot_1 << 224) != 0x00000000) {
118118
revert DisabledMode();
119119
} else if (mode == 0x00000001) {
120120
bytes4 sig = bytes4(userOp.callData[0:4]);
@@ -126,12 +126,12 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
126126
}
127127
}
128128
op.signature = userOp.signature[4:];
129-
validationData = (uint256(detail.validAfter) << 160) | (uint256(detail.validUntil) << 208);
129+
validationData = (uint256(detail.validAfter) << 208) | (uint256(detail.validUntil) << 160);
130130
} else if (mode == 0x00000002) {
131131
bytes4 sig = bytes4(userOp.callData[0:4]);
132132
// use given validator
133-
// userOp.signature[4:10] = validUntil,
134-
// userOp.signature[10:16] = validAfter,
133+
// userOp.signature[4:10] = validAfter,
134+
// userOp.signature[10:16] = validUntil,
135135
// userOp.signature[16:36] = validator address,
136136
validator = IKernelValidator(address(bytes20(userOp.signature[16:36])));
137137
bytes calldata enableData;
@@ -159,7 +159,7 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
159159
{
160160
unchecked {
161161
uint256 cursor = 88;
162-
uint256 length = uint256(bytes32(signature[56:88])); // this is enableDataLength
162+
uint256 length = uint256(bytes32(signature[56:88])); // this is enableDataLength
163163
assembly {
164164
enableData.offset := add(signature.offset, cursor)
165165
enableData.length := length
@@ -181,9 +181,7 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
181181
)
182182
);
183183
validationData = _intersectValidationData(
184-
getKernelStorage().defaultValidator.validateSignature(
185-
enableDigest, signature[cursor:cursor+length]
186-
),
184+
getKernelStorage().defaultValidator.validateSignature(enableDigest, signature[cursor:cursor + length]),
187185
uint256(bytes32(signature[4:36])) & 0xffffffffffffffffffffffff0000000000000000000000000000000000000000
188186
);
189187
assembly {
@@ -192,9 +190,9 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
192190
validationSig.length := sub(signature.length, cursor)
193191
}
194192
getKernelStorage().execution[sig] = ExecutionDetail({
193+
validAfter: uint48(bytes6(signature[4:10])),
194+
validUntil: uint48(bytes6(signature[10:16])),
195195
executor: address(bytes20(signature[36:56])),
196-
validUntil: uint48(bytes6(signature[4:10])),
197-
validAfter: uint48(bytes6(signature[10:16])),
198196
validator: IKernelValidator(address(bytes20(signature[16:36])))
199197
});
200198
}

src/abstract/KernelStorage.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import "src/interfaces/IValidator.sol";
77

88
// Defining a struct for execution details
99
struct ExecutionDetail {
10-
uint48 validUntil; // Until what time is this execution valid
11-
uint48 validAfter; // After what time is this execution valid
10+
uint48 validAfter; // Until what time is this execution valid
11+
uint48 validUntil; // After what time is this execution valid
1212
address executor; // Who is the executor of this execution
1313
IKernelValidator validator; // The validator for this execution
1414
}
@@ -95,9 +95,9 @@ contract KernelStorage {
9595
}
9696

9797
function getDisabledMode() public view returns (bytes4 disabled) {
98-
assembly {
99-
disabled := shl(224, sload(KERNEL_STORAGE_SLOT_1))
100-
}
98+
assembly {
99+
disabled := shl(224, sload(KERNEL_STORAGE_SLOT_1))
100+
}
101101
}
102102

103103
function getLastDisabledTime() public view returns (uint48) {

src/factory/AdminLessERC1967Factory.sol

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ contract AdminLessERC1967Factory {
2828

2929
/// @dev A proxy has been deployed.
3030
event Deployed(address indexed proxy, address indexed implementation);
31-
31+
3232
/// @dev `keccak256(bytes("Deployed(address,address)"))`.
3333
uint256 internal constant _DEPLOYED_EVENT_SIGNATURE =
3434
0x09e48df7857bd0c1e0d31bb8a85d42cf1874817895f171c917f6ee2cea73ec20;
@@ -39,8 +39,7 @@ contract AdminLessERC1967Factory {
3939

4040
/// @dev The ERC-1967 storage slot for the implementation in the proxy.
4141
/// `uint256(keccak256("eip1967.proxy.implementation")) - 1`.
42-
uint256 internal constant _IMPLEMENTATION_SLOT =
43-
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
42+
uint256 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
4443

4544
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
4645
/* DEPLOY FUNCTIONS */
@@ -57,32 +56,25 @@ contract AdminLessERC1967Factory {
5756
/// and returns its address.
5857
/// The value passed into this function will be forwarded to the proxy.
5958
/// Then, calls the proxy with abi encoded `data`.
60-
function deployAndCall(address implementation, bytes calldata data)
61-
internal
62-
returns (address proxy)
63-
{
59+
function deployAndCall(address implementation, bytes calldata data) internal returns (address proxy) {
6460
proxy = _deploy(implementation, bytes32(0), false, data);
6561
}
6662

6763
/// @dev Deploys a proxy for `implementation`, with `salt`,
6864
/// and returns its deterministic address.
6965
/// The value passed into this function will be forwarded to the proxy.
70-
function deployDeterministic(address implementation, bytes32 salt)
71-
internal
72-
returns (address proxy)
73-
{
66+
function deployDeterministic(address implementation, bytes32 salt) internal returns (address proxy) {
7467
proxy = deployDeterministicAndCall(implementation, salt, _emptyData());
7568
}
7669

7770
/// @dev Deploys a proxy for `implementation`, with `salt`,
7871
/// and returns its deterministic address.
7972
/// The value passed into this function will be forwarded to the proxy.
8073
/// Then, calls the proxy with abi encoded `data`.
81-
function deployDeterministicAndCall(
82-
address implementation,
83-
bytes32 salt,
84-
bytes calldata data
85-
) internal returns (address proxy) {
74+
function deployDeterministicAndCall(address implementation, bytes32 salt, bytes calldata data)
75+
internal
76+
returns (address proxy)
77+
{
8678
/// @solidity memory-safe-assembly
8779
assembly {
8880
// If the salt does not start with the zero address or the caller.
@@ -95,12 +87,10 @@ contract AdminLessERC1967Factory {
9587
}
9688

9789
/// @dev Deploys the proxy, with optionality to deploy deterministically with a `salt`.
98-
function _deploy(
99-
address implementation,
100-
bytes32 salt,
101-
bool useSalt,
102-
bytes calldata data
103-
) internal returns (address proxy) {
90+
function _deploy(address implementation, bytes32 salt, bool useSalt, bytes calldata data)
91+
internal
92+
returns (address proxy)
93+
{
10494
bytes memory m = _initCode();
10595
/// @solidity memory-safe-assembly
10696
assembly {

src/factory/KernelFactory.sol

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import "src/Kernel.sol";
88
import "src/validator/ECDSAValidator.sol";
99
import "solady/auth/Ownable.sol";
1010

11-
contract KernelFactory is AdminLessERC1967Factory, Ownable{
12-
11+
contract KernelFactory is AdminLessERC1967Factory, Ownable {
1312
mapping(address => bool) public isAllowedImplementation;
1413

1514
constructor(address _owner) {
@@ -30,11 +29,7 @@ contract KernelFactory is AdminLessERC1967Factory, Ownable{
3029
proxy = deployDeterministicAndCall(_implementation, salt, _data);
3130
}
3231

33-
function getAccountAddress(bytes calldata _data, uint256 _index)
34-
public
35-
view
36-
returns (address)
37-
{
32+
function getAccountAddress(bytes calldata _data, uint256 _index) public view returns (address) {
3833
bytes32 salt = bytes32(uint256(keccak256(abi.encodePacked(_data, _index))) & type(uint96).max);
3934
return predictDeterministicAddress(salt);
4035
}

src/interfaces/IValidator.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ interface IKernelValidator {
99
function disable(bytes calldata _data) external payable;
1010

1111
function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingFunds)
12-
external payable
12+
external
13+
payable
1314
returns (uint256);
1415

1516
function validateSignature(bytes32 hash, bytes calldata signature) external view returns (uint256);

src/test/TestKernel.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import "src/Kernel.sol";
44

55
contract TestKernel is Kernel {
66
constructor(IEntryPoint _entryPoint) Kernel(_entryPoint) {}
7-
7+
88
function sudoInitialize(IKernelValidator _defaultValidator, bytes calldata _data) external payable {
99
WalletKernelStorage storage ws = getKernelStorage();
1010
ws.defaultValidator = _defaultValidator;

src/test/TestValidator.sol

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ contract TestValidator is IKernelValidator {
1818
return 0;
1919
}
2020

21-
function validateUserOp(UserOperation calldata, bytes32 userOpHash, uint256) external payable override returns (uint256) {
21+
function validateUserOp(UserOperation calldata, bytes32 userOpHash, uint256)
22+
external
23+
payable
24+
override
25+
returns (uint256)
26+
{
2227
emit TestValidateUserOp(userOpHash);
2328
return 0;
2429
}

src/utils/KernelHelper.sol

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,19 @@ function _intersectValidationData(uint256 a, uint256 b) pure returns (uint256 va
88
// xor(a,b) == shows only matching bits
99
// and(xor(a,b), 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff) == filters out the validAfter and validUntil bits
1010
// if the result is not zero, then aggregator part is not matching
11-
switch iszero(and(xor(a,b), 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff))
11+
switch iszero(and(xor(a, b), 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff))
1212
case 1 {
1313
// validAfter
14-
let a_vd := and(0xffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff, a)
15-
let b_vd := and(0xffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff, b)
14+
let a_vd := and(0xffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff, a)
15+
let b_vd := and(0xffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff, b)
1616
validationData := xor(a_vd, mul(xor(a_vd, b_vd), gt(b_vd, a_vd)))
1717
// validUntil
18-
a_vd := and(0x000000000000ffffffffffff0000000000000000000000000000000000000000, a)
19-
b_vd := and(0x000000000000ffffffffffff0000000000000000000000000000000000000000, b)
18+
a_vd := and(0x000000000000ffffffffffff0000000000000000000000000000000000000000, a)
19+
b_vd := and(0x000000000000ffffffffffff0000000000000000000000000000000000000000, b)
2020
let until := xor(a_vd, mul(xor(a_vd, b_vd), lt(b_vd, a_vd)))
21-
if iszero(until) {
22-
until := 0x000000000000ffffffffffff0000000000000000000000000000000000000000
23-
}
21+
if iszero(until) { until := 0x000000000000ffffffffffff0000000000000000000000000000000000000000 }
2422
validationData := or(validationData, until)
2523
}
26-
default {
27-
validationData := SIG_VALIDATION_FAILED
28-
}
24+
default { validationData := SIG_VALIDATION_FAILED }
2925
}
3026
}

test/foundry/Kernel.t.sol

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ contract KernelTest is Test {
2828

2929
function setUp() public {
3030
(owner, ownerKey) = makeAddrAndKey("owner");
31-
(factoryOwner, ) = makeAddrAndKey("factoryOwner");
31+
(factoryOwner,) = makeAddrAndKey("factoryOwner");
3232
entryPoint = new EntryPoint();
3333
kernelImpl = new Kernel(entryPoint);
3434
factory = new KernelFactory(factoryOwner);
@@ -38,7 +38,17 @@ contract KernelTest is Test {
3838

3939
validator = new ECDSAValidator();
4040

41-
kernel = Kernel(payable(address(factory.createAccount(address(kernelImpl), abi.encodeWithSelector(KernelStorage.initialize.selector, validator, abi.encodePacked(owner)), 0))));
41+
kernel = Kernel(
42+
payable(
43+
address(
44+
factory.createAccount(
45+
address(kernelImpl),
46+
abi.encodeWithSelector(KernelStorage.initialize.selector, validator, abi.encodePacked(owner)),
47+
0
48+
)
49+
)
50+
)
51+
);
4252
vm.deal(address(kernel), 1e30);
4353
beneficiary = payable(address(makeAddr("beneficiary")));
4454
}
@@ -55,7 +65,17 @@ contract KernelTest is Test {
5565
}
5666

5767
function test_validate_signature() external {
58-
Kernel kernel2 = Kernel(payable(address(factory.createAccount(address(kernelImpl), abi.encodeWithSelector(KernelStorage.initialize.selector, validator, abi.encodePacked(owner)), 1))));
68+
Kernel kernel2 = Kernel(
69+
payable(
70+
address(
71+
factory.createAccount(
72+
address(kernelImpl),
73+
abi.encodeWithSelector(KernelStorage.initialize.selector, validator, abi.encodePacked(owner)),
74+
1
75+
)
76+
)
77+
)
78+
);
5979
bytes32 hash = keccak256(abi.encodePacked("hello world"));
6080
(uint8 v, bytes32 r, bytes32 s) = vm.sign(ownerKey, hash);
6181
assertEq(kernel2.isValidSignature(hash, abi.encodePacked(r, s, v)), Kernel.isValidSignature.selector);
@@ -66,8 +86,7 @@ contract KernelTest is Test {
6686
kernel2.sudoInitialize(validator, abi.encodePacked(owner));
6787

6888
UserOperation memory op = entryPoint.fillUserOp(
69-
address(kernel),
70-
abi.encodeWithSelector(Kernel.execute.selector, address(0), 0, bytes(""))
89+
address(kernel), abi.encodeWithSelector(Kernel.execute.selector, address(0), 0, bytes(""))
7190
);
7291
op.signature = abi.encodePacked(bytes4(0x00000000), entryPoint.signUserOpHash(vm, ownerKey, op));
7392
bytes32 hash = entryPoint.getUserOpHash(op);

0 commit comments

Comments
 (0)