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

Excessive Gas Consumption in Batch Execution with EXECTYPE_TRY Leading to Multiple Failures and Logging Overhead

Summary

The `_handleBatchExecution` function with `execType == EXECTYPE_TRY` attempts to execute each transaction in the batch and logs any failures without reverting the entire batch. This approach can lead to issues when handling **large return data**, causing **excessive gas consumption** and potential **failures of subsequent calls**. The `_tryExecute` function, which is used within `_handleBatchExecution`, is particularly susceptible to this issue due to its handling of return data.

Vulnerability Details

Function: _handleBatchExecution

Execution Type: EXECTYPE_TRY

Issue: Large return data can consume significant gas, leading to:

  • High gas costs for handling large return data.

  • Multiple failures within the batch due to gas depletion.

  • Inefficient execution and increased likelihood of emitting multiple failure events.

function execute(ExecutionMode mode, bytes calldata executionCalldata) external payable onlyEntryPointOrSelf withHook {
(CallType callType, ExecType execType) = mode.decodeBasic();
if (callType == CALLTYPE_SINGLE) {
_handleSingleExecution(executionCalldata, execType);
} else if (callType == CALLTYPE_BATCH) {
>>>>> _handleBatchExecution(executionCalldata, execType);
} else if (callType == CALLTYPE_DELEGATECALL) {
_handleDelegateCallExecution(executionCalldata, execType);
} else {
revert UnsupportedCallType(callType);
}
}

The _tryExecute function uses mload and mstore to allocate memory for callData and return data.
Large callData and return data can consume significant gas during memory operations.

function _tryExecute(address target, uint256 value, bytes calldata callData) internal virtual returns (bool success, bytes memory result) {
/// @solidity memory-safe-assembly
assembly {
result := mload(0x40)
calldatacopy(result, callData.offset, callData.length)
success := call(gas(), target, value, result, callData.length, codesize(), 0x00)
mstore(result, returndatasize()) // Store the length.
let o := add(result, 0x20)
returndatacopy(o, 0x00, returndatasize()) // Copy the returndata.
mstore(0x40, add(o, returndatasize())) // Allocate the memory.
}
}

Call Operation:

The call operation forwards all available gas to the target contract.
If the target contract has complex logic or loops, it can consume excessive gas, especially when handling large input data.

Return Data Handling:

The returndatacopy operation copies the return data from the call.
Large return data can further increase gas consumption, leading to potential out-of-gas errors.

Sequential Execution:

In _handleBatchExecution, each call in the batch is executed sequentially.
If one call consumes excessive gas due to large return data, subsequent calls may have insufficient gas, leading to multiple failures.

Event Emission:

In EXECTYPE_TRY mode, the function logs failures without reverting the entire batch.
Large return data increases the likelihood of emitting multiple TryExecuteUnsuccessful events, adding to the gas cost.

Impact

  • Gas Depletion: Large return data can consume excessive gas, affecting the execution of subsequent calls in the batch.

  • Execution Inefficiency: High gas costs and potential for multiple failures within the batch.

  • Event Logging Overhead: Increased number of TryExecuteUnsuccessful events due to multiple failures, further consuming gas and potentially leading to log spamming.

Tools Used

manuale review

Recommendations

Implement Gas Limits:

  • Per Call: Set a maximum gas limit for each call to prevent excessive consumption.

  • Batch Limit: Implement a total gas limit for the entire batch to ensure efficient execution.

Updates

Lead Judging Commences

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

finding-executeFromexecutor-gas-limit

Invalid, it is up to the user of the smart contract account to supply enough gas to execute transactions/operations.

Support

FAQs

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