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

Missing Negative Fee Handling in VaultReader

Summary

The getNegativeFundingFeeAmount function in VaultReader.sol returns a uint256, but the underlying value (fundingFeeAmount) can be negative (e.g., when users owe fees to the protocol). This mismatch causes underflow errors when negative values are cast to uint256.

https://github.com/CodeHawks-Contests/2025-02-gamma/blob/e5b98627a4c965e203dbb616a5f43ec194e7631a/contracts/VaultReader.sol#L96

Vulnerability Details

Faulty Code Snippet

// VaultReader.sol (Incorrect)
function getNegativeFundingFeeAmount(
bytes32 key,
MarketPrices memory prices
) external view returns (uint256) { // ⚠️ Returns uint256
// ...
return positionInfo.fees.funding.fundingFeeAmount; // fundingFeeAmount is int256
}

Type Mismatch: The function returns uint256, but fundingFeeAmount is declared as int256 (allowing negative values).

Underflow Risk: Negative values (e.g., -100) cannot be stored in uint256, causing transaction reverts.

Example Scenario

  • Negative Funding Fee: A user’s position accrues a funding fee of -100 (they owe the protocol).

  • Function Call: getNegativeFundingFeeAmount is called to retrieve the fee.

  • Underflow Revert: The function attempts to return -100 as uint256, triggering a revert.

Impact

  1. Transaction Failures: Critical functions relying on this data (e.g., withdrawals, liquidations) will fail.

  2. Inaccurate Accounting: Negative fees are misinterpreted as large positive values (2^256 - 100), corrupting protocol state.

Tools Used

Manual Review

Recommendations

Update the function’s return type to match fundingFeeAmount’s type.

Rename the function to reflect that it returns both positive/negative fees.

// VaultReader.sol (Corrected)
function getFundingFeeAmount( // ✅ Renamed for clarity
bytes32 key,
MarketPrices memory prices
) external view returns (int256) { // ✅ Correct return type
uint256 sizeInUsd = getPositionSizeInUsd(key);
if (sizeInUsd == 0) return 0;
PositionInfo memory positionInfo = gmxReader.getPositionInfo(
address(dataStore),
referralStorage,
key,
prices,
uint256(0),
address(0),
true
);
return positionInfo.fees.funding.fundingFeeAmount; // Now safely returns int256
}

After Fixes:

Return Type Correction: Changed from uint256 to int256 to accommodate negative values.

Function Renaming: Clarifies that the function returns both positive and negative fees.

Verification

Test Case 1 (Negative Fee):

fundingFeeAmount = -100

Result: Function returns -100 without reverting ✅.

Test Case 2 (Positive Fee):

fundingFeeAmount = 500

Result: Function returns 500 ✅.

Updates

Lead Judging Commences

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

Support

FAQs

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