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

Incorrect Variable Usage

Summary

  • The getPositionInfo, getNegativeFundingFeeAmount, and getPnl functions incorrectly use sizeInTokens to store the result of getPositionSizeInUsd() (USD value), while using it to check for token existence.

  • Code Snippet:

    // Flawed Implementation
    uint256 sizeInTokens = getPositionSizeInUsd(key); // Misnamed variable
    if (sizeInTokens == 0) { // Checks USD value to determine token existence
    return PositionData(..., sizeInTokens: 0, ...);
    }

Impact

  • Critical: Positions with valid token balances () but $0 USD value (e.g., token price crashes) will be:

    1. Treated as non-existent (incorrect liquidation)

    2. Excluded from protocol TVL calculations

    3. Unavailable for user interactions (withdrawals/transfers)


Proof of Concept

Test Case: test_zero_usd_position_returns_valid_token_size

function test_zero_usd_position_returns_valid_token_size() public {
bytes32 key = keccak256("zero-usd-bug");
// Mock storage returns
vm.mockCall(
DATA_STORE,
abi.encodeWithSelector( // Get USD size (0)
bytes4(keccak256("getUint(bytes32)")),
keccak256(abi.encode(key, reader.SIZE_IN_USD()))
),
abi.encode(0)
);
vm.mockCall(
DATA_STORE,
abi.encodeWithSelector( // Get token size (100e18)
bytes4(keccak256("getUint(bytes32)")),
keccak256(abi.encode(key, reader.SIZE_IN_TOKENS()))
),
abi.encode(100e18)
);
// Fetch position data
VaultReader.PositionData memory position = reader.getPositionInfo(
key,
MarketPrices(PriceProps(100, 100), PriceProps(100, 100), PriceProps(100, 100))
);
// Assertions
assertEq(position.sizeInUsd, 0, "USD size mismatch");
assertEq(position.sizeInTokens, 100e18, "Token data lost"); // Fails pre-fix
}

Expected Failure:

[FAIL] Token data lost:
Expected: 100000000000000000000
Actual: 0

Recommendations

  1. Code Fix:

    function getPositionInfo(...) ... {
    uint256 sizeInUsd = getPositionSizeInUsd(key); // Correct USD value
    uint256 sizeInTokens = getPositionSizeInTokens(key); // Correct token value
    if (sizeInUsd == 0) { // Check USD, not tokens
    return PositionData(..., sizeInTokens, ...); // Preserve token data
    }
    }
  2. Validation:

    forge test --match-test test_zero_usd_position_returns_valid_token_size -vvv
    # Pre-fix: Test fails (token size = 0)
    # Post-fix: Test passes (token size = 100e18)

Completeness Check

Item Status
Root cause analysis
Impact scenarios
Reproducible test
Fix guidance
Affected functions ❌ (Add tests for getNegativeFundingFeeAmount/getPnl)

Missing:

  • Tests for other affected functions (getNegativeFundingFeeAmount, getPnl)

  • Fuzz testing to validate across random sizes

Updates

Lead Judging Commences

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

invalid_getPosition_sizeInTokens_value_in_USD

Only check if there are no tokens. Checking if USD is 0 is equivalent. There is no problem here, even if the variable has an incorrect name: Informational.

Support

FAQs

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