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

Lack of Argument Validation in withdrawDepositTo Function

Summary

The withdrawDepositTo function in the Account contract lacks validation for its input arguments, specifically the to address and amount. This can lead to unintended behavior such as transferring funds to an invalid address or attempting to withdraw an invalid amount.

/// @notice Withdraws ETH from the EntryPoint to a specified address.
/// @param to The address to receive the withdrawn funds.
/// @param amount The amount to withdraw.
function withdrawDepositTo(address to, uint256 amount) external payable virtual onlyEntryPointOrSelf {
address entryPointAddress = _ENTRYPOINT;
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x205c2878000000000000000000000000) // `withdrawTo(address,uint256)`.
if iszero(call(gas(), entryPointAddress, 0, 0x10, 0x44, codesize(), 0x00)) {
returndatacopy(mload(0x40), 0x00, returndatasize())
revert(mload(0x40), returndatasize())
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}

Impact

  1. Invalid to Address: If the to the address is set to address(0), the ETH sent will be irrecoverably lost as it goes to the zero address, effectively burning the funds.

  • Invalid amount: If the amount is set to zero or more than the contract's balance, it could result in failed transactions or unintended loss of funds due to insufficient balance.

Tools Used

Manual Review

Recommendations

/// @notice Withdraws ETH from the EntryPoint to a specified address.
/// @param to The address to receive the withdrawn funds.
/// @param amount The amount to withdraw.
function withdrawDepositTo(address to, uint256 amount) external payable virtual onlyEntryPointOrSelf {
+ require(to != address(0), "Invalid recipient address");
+ require(amount > 0, "Invalid amount");
address entryPointAddress = _ENTRYPOINT;
uint256 gasToSend = gasleft() - 10000; // Leave some gas to complete the function
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x205c2878000000000000000000000000) // `withdrawTo(address,uint256)`.
if iszero(call(gasToSend, entryPointAddress, 0, 0x10, 0x44, 0, 0)) {
returndatacopy(mload(0x40), 0x00, returndatasize())
revert(mload(0x40), returndatasize())
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
Updates

Lead Judging Commences

0xnevi Lead Judge
12 months ago
0xnevi Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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