HardhatFoundry
30,000 USDC
View results
Submission Details
Severity: low
Invalid

`executeFromExecutor()` cannot be used because `withRegistry` checks wrong address

Summary

Nexus contract's executeFromExecutor() function cannot be used because withRegistry checks wrong address: msg.sender

Reference

Before going forward, I would like to add the reference for this finding. This issue was recently discorvered in the Safe7579's AckeeBlockchain audit. The issue report can be found here: H2: Executors cannot be used

Vulnerability Details

The function Nexus.executeFromExecutor allows ERC-7579 executor modules to execute operations on behalf of Nexus smart accounts:

function executeFromExecutor(
ExecutionMode mode,
bytes calldata executionCalldata
///@audit-issue H Executors cannot be used - withRegistry checks wrong address
) external payable onlyExecutorModule withHook withRegistry(msg.sender, MODULE_TYPE_EXECUTOR) returns (bytes[] memory returnData) {
(CallType callType, ExecType execType) = mode.decodeBasic();
// check if calltype is batch or single or delegate call
if (callType == CALLTYPE_SINGLE) {
returnData = _handleSingleExecutionAndReturnData(executionCalldata, execType);
} else if (callType == CALLTYPE_BATCH) {
returnData = _handleBatchExecutionAndReturnData(executionCalldata, execType);
} else if (callType == CALLTYPE_DELEGATECALL) {
returnData = _handleDelegateCallExecutionAndReturnData(executionCalldata, execType);
} else {
revert UnsupportedCallType(callType);
}
}

The withRegistry modifier should check that the sender module is attested as an executor module by trusted attesters with a given threshold. However, the execution always fails because the check is performed for the address of the smart account (the address of Proxy) and not the address of the executor module.

Impact

Smart account owners install a new executor module for automated token transfers. The executor module calls the executeFromExecutor function on the smartc account. The execution drops to the fallback handler, which calls Nexus.executeFromExecutor from the smart account as an external call. Given this execution, msg.sender used in the withRegistry modifier is the address of the smart account, while the executor module address is encoded at the end of the call data.

Recommendations

Replace msg.sender with _msgSender() in the withRegistry modifier to check the executor module address and allow executor modules to be used, just like the safe7579 mitigation

Updates

Lead Judging Commences

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

finding-withRegistry-wrong-msg.sender-check

Invalid, I believe there is no issue here, the caller is the executor module, so there will be no reverts. Otherwise, please provide a PoC to prove a revert.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.