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

Precision Loss in _totalAmount Calculation Leading to Large Significant Loss Over time

Summary

The _totalAmount function suffers from precision loss due to integer division in Solidity. When converting the indexToken balance and positionData.netValue into collateral token units, the calculations involve division by prices.shortTokenPrice.min. However, Solidity truncates decimal values instead of rounding them, leading to a gradual loss of value over multiple transaction.

Vulnerability Details

uint256 total = IERC20(indexToken).balanceOf(address(this)) * prices.indexTokenPrice.min / prices.shortTokenPrice.min
+ collateralToken.balanceOf(address(this))
+ positionData.netValue / prices.shortTokenPrice.min;
  • The multiplication of indexToken balance and prices.indexTokenPrice.min is performed before division by prices.shortTokenPrice.min.

  • Solidity truncates the result instead of rounding it, leading to a slight loss of precision accumulating overtime anytime totalAmount function is called.

  • The same issue occurs when dividing positionData.netValue by prices.shortTokenPrice.min.

Scenario:

  • Vault holds indexToken: 500,000 ETH

  • Vault holds collateralToken: $2,000,000 USDC
    Open position net value (positionData.netValue): $3,000,000

  • ETH Price
    (prices.indexTokenPrice.min): $1,750

  • Collateral Token Price (prices.shortTokenPrice.min): $1.2

    Step 1:

Convert indexToken Balance to Collateral Units

(500,000 * 1,750) / 1.2
= 875,000,000 / 1.2
= 729,166,666 // Expected: 729,166,666.67 (Precision lost)

Step 2:

total = 729,166,666 + 2,000,000
= 731,166,666

Step 3:

3,000,000 / 1.2
= 2,500,000 // Expected: 2,500,000.00

No loss in this step, as the values divide evenly.

Step 4:

total = 731,166,666 + 2,500,000
= 733,666,666

Analysis:

  • Expected: 733,666,666.67

  • Actual: 733,666,666

  • Precision lost: 0.67 per transaction
    Imagine 1,000 transaction per day * 356 a year
    = 356,000 transaction in a year
    0.67 * 356,000 = $238,520 lost over time

Impact

Over time, vault users lose significant funds due to precision loss, causing inaccurate NAV calculations and unexpected liquidation risks.

Tools Used

Manual Review

Recommendations

To prevent precision loss, multiply by 1e30 before division and scale back after:

uint256 total = IERC20(indexToken).balanceOf(address(this)) * prices.indexTokenPrice.min * 1e30 / prices.shortTokenPrice.min / 1e30
+ collateralToken.balanceOf(address(this))
+ positionData.netValue * 1e30 / prices.shortTokenPrice.min / 1e30;
Updates

Lead Judging Commences

n0kto Lead Judge 8 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.