@@ -76,19 +76,21 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
7676 }
7777
7878 /// @notice Returns whether a signer is authorized to perform transactions using the wallet.
79+ /* solhint-disable*/
7980 function isValidSigner (address _signer , UserOperation calldata _userOp ) public view virtual returns (bool ) {
8081 // First, check if the signer is an admin.
8182 if (_accountPermissionsStorage ().isAdmin[_signer]) {
8283 return true ;
8384 }
8485
8586 SignerPermissionsStatic memory permissions = _accountPermissionsStorage ().signerPermissions[_signer];
87+ EnumerableSet.AddressSet storage approvedTargets = _accountPermissionsStorage ().approvedTargets[_signer];
8688
8789 // If not an admin, check if the signer is active.
8890 if (
8991 permissions.startTimestamp > block .timestamp ||
9092 block .timestamp >= permissions.endTimestamp ||
91- _accountPermissionsStorage (). approvedTargets[_signer] .length () == 0
93+ approvedTargets.length () == 0
9294 ) {
9395 // Account: no active permissions.
9496 return false ;
@@ -97,28 +99,44 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
9799 // Extract the function signature from the userOp calldata and check whether the signer is attempting to call `execute` or `executeBatch`.
98100 bytes4 sig = getFunctionSignature (_userOp.callData);
99101
102+ // if address(0) is the only approved target, set isWildCard to true (wildcard approved).
103+ bool isWildCard = approvedTargets.length () == 1 && approvedTargets.at (0 ) == address (0 );
104+
100105 if (sig == AccountExtension.execute.selector ) {
101106 // Extract the `target` and `value` arguments from the calldata for `execute`.
102107 (address target , uint256 value ) = decodeExecuteCalldata (_userOp.callData);
103108
109+ // if wildcard target is not approved, check that the target is in the approvedTargets set.
110+ if (! isWildCard) {
111+ // Check if the target is approved.
112+ if (! approvedTargets.contains (target)) {
113+ // Account: target not approved.
114+ return false ;
115+ }
116+ }
117+
104118 // Check if the value is within the allowed range and if the target is approved.
105- if (
106- permissions.nativeTokenLimitPerTransaction < value ||
107- ! _accountPermissionsStorage ().approvedTargets[_signer].contains (target)
108- ) {
119+ if (permissions.nativeTokenLimitPerTransaction < value) {
109120 // Account: value too high OR Account: target not approved.
110121 return false ;
111122 }
112123 } else if (sig == AccountExtension.executeBatch.selector ) {
113124 // Extract the `target` and `value` array arguments from the calldata for `executeBatch`.
114125 (address [] memory targets , uint256 [] memory values , ) = decodeExecuteBatchCalldata (_userOp.callData);
115126
127+ // if wildcard target is not approved, check that the targets are in the approvedTargets set.
128+ if (! isWildCard) {
129+ for (uint256 i = 0 ; i < targets.length ; i++ ) {
130+ if (! approvedTargets.contains (targets[i])) {
131+ // If any target is not approved, break the loop.
132+ return false ;
133+ }
134+ }
135+ }
136+
116137 // For each target+value pair, check if the value is within the allowed range and if the target is approved.
117138 for (uint256 i = 0 ; i < targets.length ; i++ ) {
118- if (
119- permissions.nativeTokenLimitPerTransaction < values[i] ||
120- ! _accountPermissionsStorage ().approvedTargets[_signer].contains (targets[i])
121- ) {
139+ if (permissions.nativeTokenLimitPerTransaction < values[i]) {
122140 // Account: value too high OR Account: target not approved.
123141 return false ;
124142 }
@@ -131,6 +149,8 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
131149 return true ;
132150 }
133151
152+ /* solhint-enable */
153+
134154 /*///////////////////////////////////////////////////////////////
135155 External functions
136156 //////////////////////////////////////////////////////////////*/
@@ -141,12 +161,14 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
141161 }
142162
143163 /// @notice Withdraw funds for this account from Entrypoint.
144- function withdrawDepositTo (address payable withdrawAddress , uint256 amount ) public onlyAdmin {
164+ function withdrawDepositTo (address payable withdrawAddress , uint256 amount ) public {
165+ _onlyAdmin ();
145166 entryPoint ().withdrawTo (withdrawAddress, amount);
146167 }
147168
148169 /// @notice Overrides the Entrypoint contract being used.
149- function setEntrypointOverride (IEntryPoint _entrypointOverride ) public virtual onlyAdmin {
170+ function setEntrypointOverride (IEntryPoint _entrypointOverride ) public virtual {
171+ _onlyAdmin ();
150172 AccountCoreStorage.data ().entrypointOverride = address (_entrypointOverride);
151173 }
152174
@@ -195,8 +217,10 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
195217
196218 if (! isValidSigner (signer, userOp)) return SIG_VALIDATION_FAILED;
197219
198- uint48 validAfter = uint48 (_accountPermissionsStorage ().signerPermissions[signer].startTimestamp);
199- uint48 validUntil = uint48 (_accountPermissionsStorage ().signerPermissions[signer].endTimestamp);
220+ SignerPermissionsStatic memory permissions = _accountPermissionsStorage ().signerPermissions[signer];
221+
222+ uint48 validAfter = uint48 (permissions.startTimestamp);
223+ uint48 validUntil = uint48 (permissions.endTimestamp);
200224
201225 return _packValidationData (ValidationData (address (0 ), validAfter, validUntil));
202226 }
0 commit comments