Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Inability to Receive and Transfer ETH Due to Missing Payable Functions & Non-Payable Contract

Summary

Vulnerability Details

The contract InheritanceManager.sol lacks the ability to receive ETH, which leads to a critical failure when attempting to send ETH using the sendETH function. This occurs because:

  1. The constructor is not payable, meaning the contract cannot receive ETH at deployment.

  2. No receive() or fallback() function is implemented, making the contract incapable of accepting direct ETH transfers.

  3. No dedicated deposit function exists to allow the owner or users to manually send ETH to the contract.

As a result, sendETH() will always fail since the contract never holds ETH in the first place.

ROOT CAUSE

The vulnerability originates from the incorrect assumption that the contract will have ETH available for transfer. However, due to Solidity’s strict ETH handling rules, ETH must be explicitly received before it can be sent.

Breakdown of Root Causes:

  • The constructor is not marked as payable, meaning ETH cannot be sent when deploying the contract.

  • The contract has no function that accepts ETH, so direct transfers will revert.

  • The sendETH() function assumes the contract has ETH but does not check the balance before attempting the transfer.

Impact

Financial Loss & Funds Inaccessibility

  • The contract will never be able to send ETH, making sendETH() useless.

  • If the contract is expected to manage or distribute ETH, it completely fails in its purpose.

Operational Failure & User Frustration

  • Any user calling sendETH() will experience transaction failures, leading to unexpected contract behavior.

Tools Used

Manual Review

Recommendations

Implement a receive() Function

This function allows the contract to receive ETH whenever it is sent to its address.

receive() external payable {}

Make the Constructor Payable (If Needed)

If the contract needs to start with ETH, mark the constructor as payable to allow ETH deposits at deployment:

constructor() payable { owner = msg.sender; }

Add a Deposit Function for Manual ETH Transfers

To allow users to send ETH explicitly, add a depositETH() function:

function depositETH() external payable {
require(msg.value > 0, "Must send ETH");
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Missing receive() or fallback() function

Support

FAQs

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