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

Incorrect SizeDelta Calculation & User Unable to Deposit in Open Position

Description

The _createIncreasePosition function contains an incorrect calculation of sizeDelta, which does not account for token decimals correctly. Additionally, this issue prevents users from depositing into an open position.

Incorrect sizeDelta Calculation

The formula used in _createIncreasePosition is:

uint256 sizeDelta = prices.shortTokenPrice.max * amountIn * leverage / BASIS_POINTS_DIVISOR;

  • If the short token is USDC (6 decimals):

  • amountIn is in 1e6

  • shortTokenPrice.max is 1e8

  • With leverage of 2x (20,000 basis points), the resulting sizeDelta is incorrectly scaled to 1e14 instead of 1e8 (USD units).

The incorrect sizeDelta leads to an invalid fee calculation in afterOrderExecution, causing a revert due to excessive fee deduction.

function _createIncreasePosition(
bool _isLong,
uint256 acceptablePrice,
MarketPrices memory prices
) internal {
// Check available amounts to open positions
uint256 amountIn;
if (flow == FLOW.DEPOSIT) {
amountIn = depositInfo[counter].amount;
flowData = vaultReader.getPositionSizeInTokens(curPositionKey);
} else {
amountIn = collateralToken.balanceOf(address(this));
}
Order.OrderType orderType = Order.OrderType.MarketIncrease;
collateralToken.safeTransfer(address(gmxProxy), amountIn);
@=> uint256 sizeDelta = prices.shortTokenPrice.max * amountIn * leverage / BASIS_POINTS_DIVISOR;
IGmxProxy.OrderData memory orderData = IGmxProxy.OrderData({
market: market,
indexToken: indexToken,
initialCollateralToken: address(collateralToken),
swapPath: new address[](0),
isLong: _isLong,
sizeDeltaUsd: sizeDelta,
initialCollateralDeltaAmount: 0,
amountIn: amountIn,
callbackGasLimit: callbackGasLimit,
acceptablePrice: acceptablePrice,
minOutputAmount: 0
});
_gmxLock = true;
gmxProxy.createOrder(orderType, orderData);
}

Users Cannot Deposit into an Open Position

The incorrect sizeDelta affects afterOrderExecution, where feeAmount is miscalculated:

function afterOrderExecution(
bytes32 requestKey,
bytes32 positionKey,
IGmxProxy.OrderResultData memory orderResultData,
MarketPrices memory prices
) external nonReentrant {
if (msg.sender != address(gmxProxy)) {
revert Error.InvalidCall();
}
// MarketPrices memory marketPrices = gmxProxy.getMarketPrices(market);
_gmxLock = false;
// If the current action is `settle`
if (orderResultData.isSettle) {
nextAction.selector = NextActionSelector.WITHDRAW_ACTION;
emit GmxPositionCallbackCalled(requestKey, true);
return;
}
if (orderResultData.orderType == Order.OrderType.MarketIncrease) {
curPositionKey = positionKey;
if (flow == FLOW.DEPOSIT) {
uint256 amount = depositInfo[counter].amount;
@=> uint256 feeAmount = vaultReader.getPositionFeeUsd(market, orderResultData.sizeDeltaUsd, false) / prices.shortTokenPrice.min;
uint256 prevSizeInTokens = flowData;
int256 priceImpact = vaultReader.getPriceImpactInCollateral(curPositionKey, orderResultData.sizeDeltaUsd, prevSizeInTokens, prices);
uint256 increased;
if (priceImpact > 0) {
@=> increased = amount - feeAmount - uint256(priceImpact) - 1;
} else {
increased = amount - feeAmount + uint256(-priceImpact) - 1;
}
_mint(counter, increased, false, prices);
nextAction.selector = NextActionSelector.FINALIZE;

uint256 feeAmount = vaultReader.getPositionFeeUsd(market, orderResultData.sizeDeltaUsd, false) / prices.shortTokenPrice.min;

12000e30/1e8 = 12000e22

function getPositionFeeUsd(address market, uint256 sizeDeltaUsd, bool forPositiveImpact) external view returns (uint256 positionFeeAmount) {
//600000000000000000000000000
uint256 positionFeeFactor = dataStore.getUint(keccak256(abi.encode(
POSITION_FEE_FACTOR,
market,
forPositiveImpact
)));
// 2000e14 * 6e26 / 1e30 = 12000e30
positionFeeAmount = sizeDeltaUsd * positionFeeFactor / PRECISION;
}
}

Because sizeDeltaUsd is too large, the feeAmount becomes excessively high, leading to a transaction revert when subtracting amount - feeAmount.

As a result, deposits into an open position fail due to incorrect calculations and fee deductions.

Impact

No one will be able to deposit in the position also.

Transaction Failures: Increasing positions fails due to incorrect sizeDelta.

Excessive Fees: If not reverted, the system may overcharge users.

Operational Disruption: Prevents proper leverage trading.

Users Cannot Deposit in an Open Position

Deposits Fail: Users cannot add collateral to an active position.

Trading Restriction: Prevents users from increasing exposure after opening a position.

Platform Inefficiency: Reduces flexibility and usability of the trading system.

Recommendation

A proper recommendation can't be suggested but modify the sizeDelta calculation or the feeAmount calculation so it does not revert.

Updates

Lead Judging Commences

n0kto Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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