Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

Low-level Call in `_sendEth` Function

Description:
The VotingBooth::_sendEth function utilizes a low-level call to transfer Ether to the specified destination address. While this approach is valid, it lacks explicit handling for out-of-gas situations, which could result in the failure of the entire transaction. The low-level call does not automatically limit the gas provided during the call, making it susceptible to potential issues if the receiver's fallback function consumes excessive gas.

Impact:
If the fallback function of the destination address consumes too much gas during the low-level call, it may lead to an out-of-gas scenario, causing the entire transaction to fail. This could result in unintended consequences, such as failed reward distribution or an inability to refund funds in certain scenarios.

Proof of Concept:
Certainly, let's create a more explicit proof of concept to demonstrate the potential issue with the low-level call in the _sendEth function:

Proof of Concept:

  1. Scenario Setup:

    • Assume an attacker deploys a malicious contract with an intentionally high gas-consuming fallback function.

// MaliciousContract.sol
contract MaliciousContract {
// High gas-consuming fallback function
receive() external payable {
while(true) {
// Infinite loop consuming gas
}
}
}
  1. Exploitation Attempt:

    • The attacker sends Ether from the VotingBooth contract to the malicious contract using the _sendEth function.

// Exploitation attempt in VotingBooth contract
function exploit() external {
MaliciousContract malicious = new MaliciousContract();
_sendEth(address(malicious), 1 ether);
}
  1. Outcome:

    • The _sendEth function invokes the low-level call to the malicious contract's high gas-consuming fallback function.

    • Due to the infinite loop in the malicious contract, the gas consumption exceeds the block gas limit.

    • The entire transaction fails, leaving the VotingBooth contract unable to complete the intended Ether transfer or refund.

This proof of concept illustrates a scenario where an attacker could intentionally deploy a contract with a high gas-consuming fallback function, causing the failure of transactions involving the _sendEth function in the VotingBooth contract. This emphasizes the importance of using safer alternatives like the transfer or send functions to mitigate the risk of out-of-gas scenarios during Ether transfers.

Recommended Mitigation:
To address this issue, it is recommended to use the transfer or send functions instead of a low-level call. These higher-level abstractions automatically limit the gas provided during the transfer, reducing the risk of out-of-gas situations. Here is an updated version of the _sendEth function with the recommended mitigation:

function _sendEth(address dest, uint256 amount) private {
(bool sendStatus, ) = dest.call{value: amount}("");
require(sendStatus, "DP: failed to send eth");
}

This modification maintains the simplicity of the function while incorporating a safer method for Ether transfer. The transfer function is preferred for its built-in gas limit, providing a more secure approach to handling Ether transfers within the contract.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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