Integer Division Truncation in Param Calculations Causes Systematic Under/Over-Estimation (Precision Loss → Unsafe/Failed Positions)
Description:
Stratax::calculateOpenParams performs multiple chained arithmetic operations that rely on integer division. In Solidity, division truncates toward zero, so every / ... step can permanently discard precision.
This function computes critical values (flashLoanAmount, totalCollateralValueUSD, borrowValueUSD, borrowAmount, borrowValueInCollateral, flashLoanFee) using several mul / div patterns:
Even if each line looks correct, the cumulative truncation can cause borrowAmount (and the repayment feasibility check) to deviate from the intended economic model.
Impact:
Medium.
Precision loss here can lead to incorrect position sizing, with outcomes such as:
Under-borrowing → swap proceeds fail to cover flash loan + fee → revert (Insufficient borrow to repay flash loan) causing avoidable failures/DoS for otherwise valid inputs.
Over-borrowing (depending on rounding direction and where truncation happens) → larger debt than intended → higher liquidation risk / worse health factor than expected.
Inconsistent results across tokens with different decimals (6 vs 18) and low-priced assets, where truncation effects are magnified.
Because this function determines core leverage parameters, rounding errors directly affect safety and user experience.
Proof of Concept:
A representative failure pattern:
totalCollateralValueUSD is truncated down due to / 10^collateralDec
borrowValueUSD then truncates again after multiplying by ltv and safety margin
borrowAmount truncates again when dividing by borrowTokenPrice
Final check compares borrowValueInCollateral (also truncated) against minRequiredAfterSwap
With realistic inputs (e.g., 6-dec collateral, prices with 8 decimals, and non-integer conversion ratios), it’s possible for the math to land just below minRequiredAfterSwap due purely to rounding, even when the “true” real-number calculation would satisfy it.
Recommended Mitigation:
Use a consistent fixed-point strategy and aggregate multiplications before divisions, using mulDiv to preserve precision and control rounding.
A practical approach is OpenZeppelin’s Math.mulDiv (full precision) and explicitly choosing rounding direction where safety-critical:
Round up when computing amounts that must be sufficient to repay (borrowAmount, flashLoanFee, minRequiredAfterSwap)
Round down when enforcing caps (e.g., max borrow under LTV)
Example refactor pattern:
For fee and “must-cover” computations, prefer rounding up:
And similarly for borrowValueInCollateral, use mulDiv (possibly with Ceil if used as a sufficiency check).
This keeps economics stable, reduces false reverts, and makes leverage sizing safer across token decimal combinations.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.