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

Ambiguous Funding Fee Denomination in VaultReader Contract

Summary

In the VaultReader contract, a design flaw involves the function getNegativeFundingFeeAmount, which returns the value fundingFeeAmount without clarifying its denomination. Since the contract uses fundingFeeAmount multiplied by shortTokenPrice.min elsewhere, it strongly indicates that fundingFeeAmount is expressed in tokens rather than USD. However, the lack of explicit documentation in getNegativeFundingFeeAmount may lead integrators or developers to treat it incorrectly as a value in USD, resulting in inaccurate fee calculations and potential accounting inconsistencies.

Vulnerability Details

Issue: The function getNegativeFundingFeeAmount returns fundingFeeAmount without specifying whether it is measured in tokens or in USD. Elsewhere, the contract multiplies fundingFeeAmount by shortTokenPrice.min, strongly indicating that it is denominated in tokens rather than USD. However, the absence of explicit documentation in getNegativeFundingFeeAmount may cause users to assume it is already a USD value.

Cause: This design flaw stems from a lack of clarity about how fundingFeeAmount should be interpreted, leading to potential confusion or miscalculation when integrating with external systems.

Impact

If integrators incorrectly assume that fundingFeeAmount is denominated in USD rather than tokens, they may undercharge or overcharge fees, resulting in inaccuracies in accounting and potential financial discrepancies within the protocol. This design oversight can undermine the reliability of fee calculations and disrupt other components or integrations that depend on precise monetary values.

Proof of Concept

The design flaw lies in the getNegativeFundingFeeAmount function, which returns positionInfo.fees.funding.fundingFeeAmount without clarifying whether it is denominated in tokens or in USD. Since the contract multiplies this value by shortTokenPrice.min in other locations, it strongly indicates that the amount is expressed in tokens. However, in this function, it is presented as a final value—potentially misleading developers or integrators into treating it as USD, thereby risking incorrect fee calculations.

Code Analysis

Below is an excerpt of the function that demonstrates the design flaw:

function getNegativeFundingFeeAmount(
bytes32 key,
MarketPrices memory prices
) external view returns (uint256) {
uint256 sizeInTokens = getPositionSizeInUsd(key);
if (sizeInTokens == 0) return 0;
PositionInfo memory positionInfo = gmxReader.getPositionInfo(
address(dataStore),
referralStorage,
key,
prices,
uint256(0),
address(0),
true
);
// (!) 'fundingFeeAmount' is returned without clarifying if it is
// denominated in tokens or if it needs a conversion to USD
return positionInfo.fees.funding.fundingFeeAmount;
}

Explanation

  • At the line marked with ( ! ), the function exposes positionInfo.fees.funding.fundingFeeAmount without specifying its unit of measurement.

  • In other parts of the contract, this amount is multiplied by shortTokenPrice.min, implying it is likely denominated in tokens (or requires conversion to USD).

  • Failing to specify the correct unit could lead to integrators or developers erroneously treating the value as USD, resulting in accounting inaccuracies.

Vulnerable Scenario

An integrator might assume that getNegativeFundingFeeAmount already returns a value in USD and proceed to directly add or subtract it to a system's dollar-based accounting. Without first converting the token-denominated fee via shortTokenPrice.min, the following issues may arise:

  • Undercharging or overcharging funding fees.

  • Miscalculation of collateral requirements or system balances.

  • Potential financial discrepancies within the protocol or related systems.

Confirmation

Because the contract multiplies fundingFeeAmount by the token price elsewhere to arrive at a USD figure, it is evident that the value here is in tokens (or at least needs a similar conversion). The absence of explicit documentation in getNegativeFundingFeeAmount regarding its unit of measurement validates this design flaw.

Tools Used

Manual Code Review
A comprehensive line-by-line analysis of the contract’s function to identify the design flaw.

Recommendations

  • Updating the function's documentation to explicitly state that the returned fundingFeeAmount is denominated in tokens and requires conversion to USD using shortTokenPrice.min.

  • Alternatively, modify the function to perform the conversion internally and return the USD equivalent.

- return positionInfo.fees.funding.fundingFeeAmount;
+ return positionInfo.fees.funding.fundingFeeAmount * prices.shortTokenPrice.min;
Updates

Lead Judging Commences

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

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

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.