Full Report
MCDEX is a decentralized exchange and layer 2 platform that allows users to trade perpetual contracts. When performing batch trades, a user can provide the liquidity pool contract. The liquidity pool is expected to do several validations on the data. However, since this contract is controlled by the attacker, this is a major problem. Later, the Broker contracts reimburses gas expenses by transferring funds from a user's balance to a destination address. Since both of these can be chosen by an attacker, we can steal funds from any user! Simply put: we can set the pool contract to say this is a legit transaction from the pool. When, in reality, it is not. All funds in the Broker contract can be stolen by specifying that the user with funds that should pay the gas fee and putting a large sun for this. Neat bug, where calling an outside contract ended up being a catastrophic failure.
Analysis Summary
# Vulnerability: MCDEX Broker Contract Arbitrary Fund Withdrawal via External Call Trust
## CVE Details
- CVE ID: Not specified in the text (Internal or disclosed post-factum)
- CVSS Score: Not specified. **Implied Critical/High severity due to total fund loss.**
- CWE: CWE-20 (Improper Input Validation), CWE-824 (Improper Reliance on External Contract State/Behavior)
## Affected Systems
- Products: MCDEX (Decentralized Exchange and Layer 2 Platform), specifically the `Broker.sol` contract.
- Versions: Prior to the patch detailed in the provided commit.
- Configurations: Any deployment utilizing the vulnerable `batchTrade()` function where the provided liquidity pool address is user-controlled.
## Vulnerability Description
The MCDEX `Broker.sol` contract contains a `batchTrade()` function designed to process trades. This function relies on an external liquidity pool contract address provided by the caller to perform necessary data validations. Since this pool address is controllable by an attacker, they can supply an arbitrary contract that performs *no* required validation.
Subsequently, the Broker contract reimburses gas expenses by transferring funds from a user's balance to a specified destination address. Because the attacker controls the input specifying the external pool, the source user balance (whose gas fee is being paid), and the destination address for the transfer, the attacker can force the Broker contract to execute a withdrawal of any user's deposited funds into the attacker's wallet under the guise of reimbursing a legitimate gas fee for a trade that never required validation. This leads to a complete drain of funds held within the Broker contract.
## Exploitation
- Status: Not exploited in the wild (as of the report date). PoC available within the project's test suite environment.
- Complexity: Low. Requires calling a single function (`batchTrade`) with a specially crafted external contract address.
- Attack Vector: Network (Remote via smart contract interaction).
## Impact
- Confidentiality: None (Funds are transferred, not exposed).
- Integrity: **Critical**. Allows arbitrary modification of asset balances (theft).
- Availability: Low (The service remains available, but user funds are stolen).
## Remediation
### Patches
- The vulnerability was fixed by adding a validation of the signature provided by the caller within the `batchTrade()` function.
- Commit reference: `https://github.com/mcdexio/mai-protocol-v3/commit/ea81ab32e0963501be13cc3710af56751783c1e5` (Link defanged)
### Workarounds
- No specific external workarounds were detailed, as a full patch was deployed. Temporary mitigation would involve disabling the `batchTrade` function or enforcing whitelisting for liquidity pool contract addresses involved in gas reimbursement routines until the patch could be applied.
## Detection
- Indicators of Compromise: Unexpected fund transfers originating from the Broker contract destined for an address that does not match expected fee/gas destinations, especially those associated with `batchTrade` calls.
- Detection methods and tools: Monitoring contract state changes and transaction traces for `batchTrade` calls where the `liquidityPool` parameter points to an unverified or unusual contract address, followed by fund movements.
## References
- Vendor advisories: MCDEX Bugfix Review via Immunefi.
- Relevant links: `hXXps://medium.com/immunefi/mcdex-insufficient-validation-bugfix-review-e270e885c572`