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

Unsafe Token Transfer in _createIncreasePosition in PerpetualVault.sol

Summary

An unsafe token transfer occurs in _createIncreasePosition, where collateral tokens are transferred to gmxProxy before confirming order creation. If the order fails, the funds could be stuck.

Vulnerability Details

  • Collateral tokens are transferred before ensuring successful order creation.

  • The function safeTransfer prevents direct transfer failures but does not handle failures in the subsequent order creation process (gmxProxy.createOrder).

  • If createOrder fails, there is no recovery mechanism to reclaim transferred tokens.

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);

Impact

  • If gmxProxy.createOrder fails, tokens remain in gmxProxy, potentially leading to fund loss.

  • There is no rollback mechanism to recover these tokens in case of failure.

  1. Premature Transfer: Collateral tokens are transferred before verifying whether the order can be successfully created.

  2. No Recovery Mechanism: If createOrder fails, the contract lacks a function to reclaim tokens from gmxProxy.

  3. Order Failure Scenarios: createOrder might fail due to insufficient execution gas, disabled GMX execution, or invalid order parameters.

Tools Used

  • Manual Code Review

  • Static Analysis Tools (Slither, MythX)

Recommendations

  1. Verify Order Creation Feasibility Before Transferring Tokens

    • Ensure createOrder will succeed before calling safeTransfer.

  2. Use a Two-Step Process for Token Transfer:

    • First, approve tokens for transfer.

    • Transfer only after createOrder succeeds.

  3. Implement a Fallback Recovery Mechanism:

    • Add a function to retrieve stuck tokens in case of order failure.

    • Example:

    function recoverTokens(address recipient) external onlyOwner {
    uint256 balance = collateralToken.balanceOf(address(gmxProxy));
    collateralToken.safeTransfer(recipient, balance);
    }
Updates

Lead Judging Commences

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

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:

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.