Tall Grape Wombat
Medium
The withdrawETH
function in the contract lacks a check for whether the user has a zero balance before proceeding with the withdrawal logic. This oversight can lead to wasted gas and a confusing user experience. Additionally, it may expose the protocol to minor abuse scenarios, such as repeated zero-value transactions or event spamming.
function withdrawETH(address, uint256 amount, address to) external override {
IAToken aWETH = IAToken(POOL.getReserveAToken(address(WETH)));
uint256 userBalance = aWETH.balanceOf(msg.sender);
uint256 amountToWithdraw = amount;
// if amount is equal to uint(-1), the user wants to redeem everything
if (amount == type(uint256).max) {
amountToWithdraw = userBalance;
}
aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
POOL.withdraw(address(WETH), amountToWithdraw, address(this));
WETH.withdraw(amountToWithdraw);
_safeTransferETH(to, amountToWithdraw);
}
The function does not explicitly check if the user’s balance is zero before executing subsequent steps.
No response
No response
No response
- The
aWETH.transferFrom
function will likely revert if the user attempts to transfer tokens they do not own. However, this happens after other potentially gas-costly operations have already executed, unnecessarily consuming gas.
- Users with zero balance receive no meaningful error message until a later stage, leading to poor user experience.
- Repeated calls with zero balance could lead to minor denial-of-service or spamming scenarios.
No response
Add a check for zero balance at the start of the function to prevent further execution when the user has no funds to withdraw.
function withdrawETH(address, uint256 amount, address to) external override {
IAToken aWETH = IAToken(POOL.getReserveAToken(address(WETH)));
uint256 userBalance = aWETH.balanceOf(msg.sender);
// Ensure the user has a non-zero balance
require(userBalance > 0, "Withdraw failed: zero balance");
uint256 amountToWithdraw = amount;
// If the user wants to redeem everything
if (amount == type(uint256).max) {
amountToWithdraw = userBalance;
}
aWETH.transferFrom(msg.sender, address(this), amountToWithdraw);
POOL.withdraw(address(WETH), amountToWithdraw, address(this));
WETH.withdraw(amountToWithdraw);
_safeTransferETH(to, amountToWithdraw);
}
-
Gas Optimization:
- The function exits early when the balance is zero, avoiding unnecessary operations.
-
Improved User Experience:
- Users receive a clear and immediate error message (“Withdraw failed: zero balance”) when they have no funds to withdraw.
-
Security Hardening:
- Prevents spamming or minor abuse scenarios.