DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: high
Invalid

Reentrancy Vulnerability in createTradingAccountAndMulticall Function

Summary

The createTradingAccountAndMulticall function in the TradingAccountBranch contract is vulnerable to reentrancy attacks due to insufficient validation of the data payload. This vulnerability allows attackers to exploit reentrancy opportunities and manipulate contract state or access functions unauthorizedly.

Vulnerability Details

The createTradingAccountAndMulticall function allows users to create a new trading account and execute multiple calls within a single transaction. However, the function does not adequately validate the data payload, enabling reentrancy attacks. Attackers can exploit this by crafting malicious payloads that call back into the vulnerable function, causing unexpected behaviors or unauthorized state changes.

function createTradingAccountAndMulticall(
bytes[] calldata data,
bytes memory referralCode,
bool isCustomReferralCode
)
external
payable
virtual
returns (bytes[] memory results)
{
uint128 tradingAccountId = createTradingAccount(referralCode, isCustomReferralCode);
results = new bytes[](data.length);
for (uint256 i; i < data.length; i++) {
bytes memory dataWithAccountId = bytes.concat(data[i][0:4], abi.encode(tradingAccountId), data[i][4:]);
(bool success, bytes memory result) = address(this).delegatecall(dataWithAccountId);
if (!success) {
uint256 len = result.length;
assembly {
revert(add(result, 0x20), len)
}
}
results[i] = result;
}
}

Impact

The impact of this vulnerability is significant as it could lead to the following issues:

  • Unauthorized access to contract functions

  • Manipulation of contract state

  • Potential financial loss due to reentrancy attacks

Tools Used

  • Manual code review

  • LLM

Recommendations

  1. Validate Payload Data: Ensure that the data payload is thoroughly validated before execution to prevent malicious input from causing unintended behaviors.

  2. Ensure State Changes Before External Calls: Make sure that all critical state changes are performed before any external calls.

  3. Implement Access Control Mechanisms: Use access control checks to ensure that only authorized entities can call sensitive functions.



    Example Fix:

    function createTradingAccountAndMulticall(
    bytes[] calldata data,
    bytes memory referralCode,
    bool isCustomReferralCode
    )
    external
    payable
    virtual
    returns (bytes[] memory results)
    {
    // Ensure state changes before any external calls
    uint128 tradingAccountId = createTradingAccount(referralCode, isCustomReferralCode);
    // Initialize results array
    results = new bytes[](data.length);
    // Iterate through data array and validate each call
    for (uint256 i; i < data.length; i++) {
    // Validate function selector
    bytes4 selector = bytes4(data[i][:4]);
    require(isValidFunctionSelector(selector), "Invalid function selector");
    // Concatenate the tradingAccountId with the function call data
    bytes memory dataWithAccountId = bytes.concat(data[i][0:4], abi.encode(tradingAccountId), data[i][4:]);
    // Make external call
    (bool success, bytes memory result) = address(this).delegatecall(dataWithAccountId);
    // Handle failure
    if (!success) {
    uint256 len = result.length;
    assembly {
    revert(add(result, 0x20), len)
    }
    }
    // Store result
    results[i] = result;
    }
    }
    // Helper function to validate function selectors
    function isValidFunctionSelector(bytes4 selector) internal pure returns (bool) {
    return (
    selector == this.someFunction.selector ||
    selector == this.anotherFunction.selector ||
    // Add more valid function selectors as needed
    false
    );
    }
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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