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

The InheritanceManager Contract Lacks a Mechanism to Receive Ether, Hindering Its Functionality as an Inheritance Wallet

Summary

The InheritanceManager contract, in its current implementation, lacks a mechanism to directly receive Ether. While it includes a sendETH function to send Ether, there is no function, receive(), or fallback() method to enable external users or contracts to deposit Ether into the contract. This limitation critically hinders the contract's intended functionality as an inheritance wallet, as users cannot deposit Ether into it.


Vulnerability Details

1. Lack of receive() or fallback() Functions

  • The contract does not implement a receive() or fallback() function, which are essential for handling Ether sent to the contract without a specific function call.

    • The receive() function is specifically designed to handle direct Ether transfers.

    • The fallback() function is a general-purpose function that executes when no other function signature matches the call.

2. No Payable Function for Ether Deposit

  • The contract does not include any payable functions designed to accept Ether as input.

    • The sendETH function is used to send Ether out of the contract but cannot receive Ether (it lacks the payable keyword).

    • The contractInteractions function could potentially receive Ether, but there is no external way to provide the _value argument.

3. Contract Intended to Hold Assets

  • Based on its functionality related to inheritance and asset transfer, the contract is expected to hold assets, including Ether. However, the inability to receive Ether directly contradicts this purpose.


Code Snippets

sendETH Function

function sendETH(uint256 _amount, address _to) external nonReentrant onlyOwner {
(bool success,) = _to.call{value: _amount}("");
require(success, "Transfer Failed");
_setDeadline();
}

contractInteractions Function

function contractInteractions(
address _target,
bytes calldata _payload,
uint256 _value,
bool _storeTarget
) external nonReentrant onlyOwner {
(bool success, bytes memory data) = _target.call{value: _value}(_payload);
require(success, "Interaction Failed");
if (_storeTarget) {
interactions[_target] = data;
}
}

Impact

1. Loss of Functionality

  • Users cannot deposit Ether into the contract, rendering it impossible to use the contract as an inheritance wallet for Ether. This directly contradicts the contract's core purpose.

2. Reduced Utility

  • The inability to deposit Ether severely limits the contract's usefulness. It can only manage ERC20 tokens and handle Ether generated internally through interactions with other contracts (a highly limited and indirect method).

3. Unexpected Behavior

  • If Ether is accidentally sent to the contract, it will be permanently stuck, as there is no mechanism to retrieve or interact with it.


Tools Used

  • Manual Code Review


Recommendations

1. Implement a receive() Function

  • Add a receive() function to the contract. This is the most straightforward and recommended way to handle Ether deposits.

receive() external payable {}

2. Consider a depositETH() Function

  • For added clarity or more complex scenarios, implement a named depositETH() function. This function can include additional logic or modifiers if needed.

function depositETH() external payable {
_setDeadline(); // Update the deadline on every deposit.
}

3. Make contractInteractions Payable

  • Modify the contractInteractions function to include the payable keyword, enabling it to receive Ether.

function contractInteractions(
address _target,
bytes calldata _payload,
uint256 _value,
bool _storeTarget
) external payable nonReentrant onlyOwner {
(bool success, bytes memory data) = _target.call{value: _value}(_payload);
require(success, "Interaction Failed");
if (_storeTarget) {
interactions[_target] = data;
}
}
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.