DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Unvalidated GMX Swap Path Leading to Fund Loss

Summary

The _runSwap function decodes and uses a gPath (swap path) from off-chain metadata without validation. A malicious keeper can craft a gPath that routes swaps through untrusted or malicious pools/tokens, enabling fund theft or manipulation.


Vulnerability Details

Affected Code

// Inside _runSwap (GMX swap logic)
(address[] memory gPath, uint256 amountIn, uint256 minOutputAmount) =
abi.decode(data, (address[], uint256, uint256));
// Transfers tokens and executes swap via GMX
IERC20(tokenIn).safeTransfer(address(gmxProxy), amountIn);
gmxProxy.createOrder(..., gPath, ...);

Root Cause

  • Unverified gPath: The swap path (gPath) is entirely controlled by the keeper and not validated by the contract.

  • Malicious Routing: A compromised keeper can route swaps through malicious or low-liquidity pools to:

    • Extract value via manipulated prices.

    • Drain funds via reentrancy or fake pools.

Example Attack Scenario

  1. Keeper Submits Malicious gPath:

    • gPath = [collateralToken, attackerToken, indexToken], where attackerToken is a malicious ERC20.

  2. Swap Execution:

    • The contract transfers collateralToken to gmxProxy, which routes through attackerToken.

    • The attackerToken contract drains funds during the swap (e.g., via a fake transferFrom implementation).


Impact

  • Fund Theft: Malicious gPath can siphon tokens from the contract.

  • Slippage Losses: Low-liquidity paths cause high slippage, reducing output.

  • Token Locking: Swaps involving non-whitelisted tokens disrupt vault operations.


Proof of Concept (PoC)

Step-by-Step Exploit

  1. Keeper Prepares Malicious Metadata:

    • Encodes gPath with a malicious token (e.g., attackerToken).

  2. User Triggers run Function:

    • The _runSwap function decodes and executes the malicious gPath.

  3. Malicious Token Drains Funds:

    • The attackerToken contract hijacks the swap, stealing collateralToken.


Recommended Mitigations

1. Validate gPath On-Chain

Restrict gPath to trusted tokens (e.g., collateralToken and indexToken):

for (uint256 i = 0; i < gPath.length; i++) {
require(
gPath[i] == address(collateralToken) || gPath[i] == indexToken,
"Invalid token in path"
);
}

2. Use Pre-Approved Swap Paths

Hardcode allowed paths (e.g., direct swaps between collateralToken and indexToken):

address[] memory allowedPath = new address[](2);
allowedPath[0] = address(collateralToken);
allowedPath[1] = indexToken;
require(
keccak256(abi.encode(gPath)) == keccak256(abi.encode(allowedPath)),
"Invalid path"
);

3. Implement Path Sanitization Logic

Use a whitelist of approved pools/routers for GMX swaps:

address public constant GMX_ROUTER = 0x...;
require(gPath[0] == GMX_ROUTER, "Invalid router");
Updates

Lead Judging Commences

n0kto Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Suppositions

There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.

n0kto Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Suppositions

There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.

Support

FAQs

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