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

Critical Lack of Slippage Protection in settle() Function

Summary

The settle() function in GmxProxy.sol uses hardcoded values for critical price parameters without any slippage protection, potentially exposing users to significant losses during market volatility.

Vulnerability Details

In the settle() function, several critical price-related parameters are hardcoded to either 0 or 1:

CreateOrderParamsNumbers memory paramsNumber = CreateOrderParamsNumbers({
sizeDeltaUsd: 0,
initialCollateralDeltaAmount: 1, // Hardcoded to 1
triggerPrice: 0, // Hardcoded to 0
acceptablePrice: 0, // No slippage protection
minOutputAmount: 0, // No minimum output guarantee
// ...
});

The issues are:

  1. acceptablePrice: 0 - No maximum slippage limit

  2. minOutputAmount: 0 - No minimum output guarantee

  3. initialCollateralDeltaAmount: 1 - Hardcoded minimal value

This configuration means:

  • Orders can be executed at any price

  • No minimum received amount is enforced

  • Users have no protection against sandwich attacks or price manipulation

Impact

Severity: High

  • Likelihood: High (market volatility is common)

  • Impact: Critical (can lead to significant financial losses)

Potential attack scenarios:

  1. MEV bots can sandwich the settlement transaction

  2. During high volatility, orders could be executed at extremely unfavorable prices

  3. No guarantee on minimum output amount could lead to significant value loss

Tools Used

  • Manual code review

  • Historical MEV attack analysis

Recommendations

  1. Add slippage protection parameters to the OrderData struct:

struct OrderData {
// ... existing fields ...
uint256 maxSlippage; // Maximum acceptable slippage in basis points
uint256 minOutputAmount; // Minimum amount to receive
}
  1. Implement proper slippage checks in the settle() function:

function settle(IGmxProxy.OrderData memory orderData) external returns (bytes32) {
// ... existing checks ...
// Calculate acceptable price based on current price and max slippage
uint256 currentPrice = getMarketPrices(orderData.market).indexTokenPrice;
uint256 acceptablePrice = orderData.isLong
? currentPrice * (10000 + orderData.maxSlippage) / 10000 // Long position
: currentPrice * (10000 - orderData.maxSlippage) / 10000; // Short position
CreateOrderParamsNumbers memory paramsNumber = CreateOrderParamsNumbers({
sizeDeltaUsd: orderData.sizeDeltaUsd,
initialCollateralDeltaAmount: orderData.initialCollateralDeltaAmount,
triggerPrice: currentPrice,
acceptablePrice: acceptablePrice,
executionFee: positionExecutionFee,
callbackGasLimit: orderData.callbackGasLimit,
minOutputAmount: orderData.minOutputAmount, // Use provided minimum
validFromTime: 0
});
// ... rest of the function
}
  1. Add proper validation:

require(orderData.maxSlippage > 0 && orderData.maxSlippage <= 1000, "Invalid slippage"); // Max 10%
require(orderData.minOutputAmount > 0, "Invalid min output");
Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!