@@ -11,6 +11,8 @@ import "./abstract/Compatibility.sol";
1111import "./abstract/KernelStorage.sol " ;
1212import "./utils/KernelHelper.sol " ;
1313
14+ import "forge-std/console.sol " ;
15+
1416enum Operation {
1517 Call,
1618 DelegateCall
@@ -89,11 +91,19 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
8991 /// @param userOpHash The hash of the user operation
9092 /// @param missingAccountFunds The funds needed to be reimbursed
9193 /// @return validationData The data used for validation
92- function validateUserOp (UserOperation calldata userOp , bytes32 userOpHash , uint256 missingAccountFunds )
94+ function validateUserOp (UserOperation memory userOp , bytes32 userOpHash , uint256 missingAccountFunds )
9395 external
9496 payable
9597 returns (uint256 validationData )
9698 {
99+ bytes calldata userOpSignature;
100+ uint256 userOpEndOffset;
101+ assembly {
102+ userOpEndOffset := add (calldataload (0x04 ), 0x24 )
103+ userOpSignature.offset := add (calldataload (add (userOpEndOffset, 0x120 )), userOpEndOffset)
104+ userOpSignature.length := calldataload (sub (userOpSignature.offset, 0x20 ))
105+ }
106+
97107 if (msg .sender != address (entryPoint)) {
98108 revert NotEntryPoint ();
99109 }
@@ -102,43 +112,49 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
102112 storage_slot_1 := sload (KERNEL_STORAGE_SLOT_1)
103113 }
104114 // mode based signature
105- bytes4 mode = bytes4 (userOp.signature [0 :4 ]); // mode == 00..00 use validators
115+ bytes4 mode = bytes4 (userOpSignature [0 :4 ]); // mode == 00..00 use validators
106116 // mode == 0x00000000 use sudo validator
107117 // mode == 0x00000001 use given validator
108118 // mode == 0x00000002 enable validator
109- UserOperation memory op = userOp;
110119 IKernelValidator validator;
111120 if (mode == 0x00000000 ) {
112121 // sudo mode (use default validator)
113- op.signature = userOp.signature [4 :];
122+ userOpSignature = userOpSignature [4 :];
114123 assembly {
115124 validator := shr (80 , storage_slot_1)
116125 }
117126 } else if (mode & (storage_slot_1 << 224 ) != 0x00000000 ) {
118127 revert DisabledMode ();
119128 } else if (mode == 0x00000001 ) {
120- bytes4 sig = bytes4 (userOp.callData[0 :4 ]);
121- ExecutionDetail storage detail = getKernelStorage ().execution[sig];
129+ bytes calldata userOpCallData;
130+ assembly {
131+ userOpCallData.offset := add (calldataload (add (userOpEndOffset, 0x40 )), userOpEndOffset)
132+ userOpCallData.length := calldataload (sub (userOpCallData.offset, 0x20 ))
133+ }
134+ ExecutionDetail storage detail = getKernelStorage ().execution[bytes4 (userOpCallData[0 :4 ])];
122135 validator = detail.validator;
123136 if (address (validator) == address (0 )) {
124137 assembly {
125138 validator := shr (80 , storage_slot_1)
126139 }
127140 }
128- op.signature = userOp.signature [4 :];
141+ userOpSignature = userOpSignature [4 :];
129142 validationData = (uint256 (detail.validAfter) << 208 ) | (uint256 (detail.validUntil) << 160 );
130143 } else if (mode == 0x00000002 ) {
131- bytes4 sig = bytes4 (userOp.callData[0 :4 ]);
144+ bytes calldata userOpCallData;
145+ assembly {
146+ userOpCallData.offset := add (calldataload (add (userOpEndOffset, 0x40 )), userOpEndOffset)
147+ userOpCallData.length := calldataload (sub (userOpCallData.offset, 0x20 ))
148+ }
132149 // use given validator
133- // userOp.signature [4:10] = validAfter,
134- // userOp.signature [10:16] = validUntil,
135- // userOp.signature [16:36] = validator address,
136- validator = IKernelValidator (address (bytes20 (userOp.signature [16 :36 ])));
150+ // userOpSignature [4:10] = validAfter,
151+ // userOpSignature [10:16] = validUntil,
152+ // userOpSignature [16:36] = validator address,
153+ validator = IKernelValidator (address (bytes20 (userOpSignature [16 :36 ])));
137154 bytes calldata enableData;
138- bytes calldata remainSig;
139- (validationData, enableData, remainSig) = _approveValidator (sig, userOp.signature );
155+ (validationData, enableData, userOpSignature) =
156+ _approveValidator (bytes4 (userOpCallData[ 0 : 4 ]), userOpSignature );
140157 validator.enable (enableData);
141- op.signature = remainSig;
142158 } else {
143159 return SIG_VALIDATION_FAILED;
144160 }
@@ -148,8 +164,9 @@ contract Kernel is EIP712, Compatibility, KernelStorage {
148164 }
149165 //ignore failure (its EntryPoint's job to verify, not account.)
150166 }
167+ userOp.signature = userOpSignature;
151168 validationData =
152- _intersectValidationData (validationData, validator.validateUserOp (op , userOpHash, missingAccountFunds));
169+ _intersectValidationData (validationData, validator.validateUserOp (userOp , userOpHash, missingAccountFunds));
153170 return validationData;
154171 }
155172
0 commit comments