Usage of transfer to send ETH can prevent receiving
Description
The protocol employs Solidity's .transfer
method to send Ethereum (ETH) to recipients. However, .transfer
is limited to a hardcoded gas amount of 2,300, which may not be sufficient for contracts with logic in their fallback function. Consequently, these contracts may revert during the transaction. Additionally, the use of a hardcoded gas stipend may not be compatible with future changes to Ethereum gas costs, posing a potential risk to the protocol's long-term viability.
Impact
function withdrawETH(uint256 _amount) external payable onlyOwner {
if (availableBalance() < _amount) {
revert InsufficientAvailableLiquidity();
}
address payable to = payable(_msgSender());
to.transfer(_amount);
emit ETHWithdrawn(_amount);
}
The withdrawETH
function sends ETH to the designated recipient (msg.sender
) using the to.transfer(_amount)
method. However, if the recipient is a contract that incurs computational costs exceeding 2,300 gas upon receiving ETH, it will be unable to receive the funds. This poses a risk of failed transactions for contracts that have high gas costs, potentially leaving the designated recipient without access to their funds.
Recommendations
We suggest using the .call
method to send ETH and verifying the return value to confirm a successful transfer. Solidity by Example offers a helpful guide on choosing the appropriate method for sending ETH, which can be found here: https://solidity-by-example.org/sending-ether/↗.
Furthermore, since the withdrawETH
function does not intend to receive ETH, the payable
keyword can be removed.
Remediation
This issue has been acknowledged by Wasabi, and a fix was implemented in commit 01ee7727↗.