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

Arbitrary External Calls in contractInteractions Allow Potential Misuse and Security Risks

Summary

The InheritanceManager::contractInteractions function allows the contract owner to execute arbitrary external calls with any calldata and an optional ETH transfer. While the function is restricted to onlyOwner, this design introduces significant risks if the owner's private key is compromised or if the owner mistakenly interacts with a malicious contract.

This function effectively grants the owner unrestricted execution power, making it equivalent to an externally owned account (EOA) in terms of contract interaction. If misused or compromised, it could lead to loss of funds, execution of unintended operations, or exposure to external contract vulnerabilities.


Vulnerability Details

function contractInteractions(address _target, bytes calldata _payload, uint256 _value, bool _storeTarget)
external
nonReentrant
onlyOwner
{
// @audit-issue Allows arbitrary contract calls, which may result in unintended interactions, loss of funds, or security vulnerabilities if the owner interacts with a malicious contract
@> (bool success, bytes memory data) = _target.call{value: _value}(_payload);
require(success, "interaction failed");
if (_storeTarget) {
interactions[_target] = data;
}
}

Issue Explanation

  1. Owner Key Compromise Could Lead to Total Loss of Funds

    • Since contractInteractions allows arbitrary calls, if an attacker gains access to the owner's private key, they could call external contracts (e.g., swap all assets to another address or withdraw all ETH and tokens).

    • This effectively grants full control over the contract’s assets to whoever controls the owner key.

  2. No Whitelist or Safety Checks on _target

    • The function does not restrict which contracts can be called. The owner could unknowingly interact with:

      • Malicious smart contracts that drain assets.

      • Buggy or unverified contracts that cause unexpected state changes.

      • Blacklisted contracts that could have compliance implications.

  3. Potential for Reentrancy and Unexpected Behavior

    • Although nonReentrant is applied, if it is not correctly implemented, reentrancy may still be possible if a called contract has callbacks into this contract.

    • Even without reentrancy, calling unknown contracts introduces execution risk, such as failed transactions, state corruption, or infinite loops.


Impact

  1. Potential Total Loss of Funds

    • If the owner's private key is compromised, all contract assets could be drained via arbitrary calls.

  2. Unrestricted Execution Power Without Verification

    • The owner may mistakenly interact with malicious or high-risk contracts.

  3. Risk of Contract Misbehavior

    • External contract calls could result in unintended state changes or vulnerabilities being introduced in the future.

  4. Unnecessary Storage and Gas Costs

    • Tracking every call through _storeTarget could increase contract storage overhead and operational costs.


Tools Used

  • Manual Review


Recommendations

Restrict Allowed Targets (_target)

Limit contractInteractions to interact only with whitelisted contracts.

mapping(address => bool) public approvedContracts;
function setApprovedContract(address _contract, bool _status) external onlyOwner {
approvedContracts[_contract] = _status;
}
function contractInteractions(address _target, bytes calldata _payload, uint256 _value, bool _storeTarget)
external
nonReentrant
onlyOwner
{
require(approvedContracts[_target], "Unauthorized target contract");
(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 5 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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