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

Function createTradingAccountAndMulticall Delegatecall

Summary

The createTradingAccountAndMulticall function uses delegatecall to execute multiple function calls in the context of the TradingAccountBranch contract. This can be dangerous if the input data is not properly sanitized, leading to potential security risks such as unauthorized state changes or fund transfers.

Vulnerability Details

https://github.com/Cyfrin/2024-07-zaros/blob/d687fe96bb7ace8652778797052a38763fbcbb1b/src/perpetuals/branches/TradingAccountBranch.sol#L285-L311

  1. Craft Malicious Payload:

    The attacker needs to encode the function call to withdrawMargin with parameters that would transfer funds to their address.

bytes memory maliciousPayload = abi.encodeWithSignature(
"withdrawMargin(uint128,address,uint256)",
tradingAccountId, // The ID of the trading account to withdraw from
collateralType, // The type of collateral to withdraw
amountToWithdraw // The amount to withdraw
);
  1. Call createTradingAccountAndMulticall with Malicious Payload:

    The attacker prepares the data array containing the malicious payload and calls the createTradingAccountAndMulticall function.

bytes[] memory data = new bytes[](1);
data[0] = maliciousPayload;
tradingAccountBranch.createTradingAccountAndMulticall(data, referralCode, isCustomReferralCode);
  • **Execution via **delegatecall:

    • The createTradingAccountAndMulticall function processes the data array.

    • It constructs the dataWithAccountId by appending the tradingAccountId to the malicious payload.

    • The delegatecall executes the malicious payload in the context of the TradingAccountBranch contract.

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;
}
  • Unauthorized Fund Transfer:

    • The withdrawMargin function is executed within the TradingAccountBranch contract's context.

    • The function transfers the specified amount of collateral from the contract to the attacker's address. Since delegatecall preserves the context, the state changes made by withdrawMargin directly affect the TradingAccountBranch contract.

Impact

  • Unauthorized Fund Transfers

  • State Manipulation

  • Access Control Bypass

Tools Used

Manual Review

Recommendations

  • Validate the data array to ensure only allowed functions can be called.

  • Implement strict access control checks in all functions that can be called via delegatecall.

  • Use reentrancy guards to prevent reentrant calls that could exploit the contract's state.

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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