DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: medium
Valid

getExecutionGasLimit() reports a lower gas limit due to gasPerSwap miscalculation

Description

When a user calls deposit() or withdraw(), these functions internally call: _payExecutionFee --> PerpetualVault::getExecutionGasLimit() --> GmxProxy::getExecutionGasLimit(). The function getExecutionGasLimit() in GmxProxy.sol fetches gasPerSwap correctly as:

uint256 gasPerSwap = dataStore.getUint(SINGLE_SWAP_GAS_LIMIT);

but then assumes the swapPath length to be 1 & never bothers to multiply it with the correct swap hops.

Let's have a look at the GMX implementation. We can see here that SINGLE_SWAP_GAS_LIMIT key is retuned by the singleSwapGasLimitKey() function.

// @dev key for single swap gas limit
// @return key for single swap gas limit
function singleSwapGasLimitKey() internal pure returns (bytes32) {
return SINGLE_SWAP_GAS_LIMIT;
}

We can also see that a function like estimateExecuteDecreaseOrderGasLimit() (among many others) calculates the gas limit in the following manner:

// @dev the estimated gas limit for decrease orders
// @param dataStore DataStore
// @param order the order to estimate the gas limit for
function estimateExecuteDecreaseOrderGasLimit(DataStore dataStore, Order.Props memory order) internal view returns (uint256) {
uint256 gasPerSwap = dataStore.getUint(Keys.singleSwapGasLimitKey());
uint256 swapCount = order.swapPath().length;
if (order.decreasePositionSwapType() != Order.DecreasePositionSwapType.NoSwap) {
swapCount += 1;
}
@---> return dataStore.getUint(Keys.decreaseOrderGasLimitKey()) + gasPerSwap * swapCount + order.callbackGasLimit();
}

Notice the gasPerSwap * swapCount term in the return statement. The Gamma implementation misses this or assumes that tokens like WBTC or LINK on both Arbitrum and Avalanche chains will be swappable with WETH in one hop, which is not necessarily true and GMX may use an optimized swap path with more than one hops.

Impact

User may end up paying less than required execution fee and the Keepers end up paying additional amount from their own pockets.

As the contest page specifies for Depositors:

Must provide sufficient execution fees for operations

Recommendation

Either fetch the swapPath hops from GMX and multiply that to gasPerSwap OR increase the buffer on top of the calculated gas limit to stay in the safe zone.

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_swapPath_does_not_increase_the_executionFee

Likelihood: Low/Medium, when swapPath has more than 1 item. Impact: Medium/High, could lead to not enough fee collected to execute the transaction in GMX

Appeal created

riceee Auditor
6 months ago
n0kto Lead Judge
6 months ago
n0kto Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_swapPath_does_not_increase_the_executionFee

Likelihood: Low/Medium, when swapPath has more than 1 item. Impact: Medium/High, could lead to not enough fee collected to execute the transaction in GMX

Support

FAQs

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