Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: medium
Likelihood: medium

Precision Loss From Integer Division in Stratax::calculateUnwindParams May Under/Overestimate Collateral Withdrawal

Author Revealed upon completion

Precision Loss From Integer Division in Stratax::calculateUnwindParams May Under/Overestimate Collateral Withdrawal

Description:
The function computes collateralToWithdraw using integer division:

function calculateUnwindParams(address _collateralToken, address _borrowToken)
public
view
returns (uint256 collateralToWithdraw, uint256 debtAmount)
{
...
@> collateralToWithdraw = (debtTokenPrice * debtAmount * 10 ** IERC20(_collateralToken).decimals())
/ (collateralTokenPrice * 10 ** IERC20(_borrowToken).decimals());
// Account for 5% slippage in swap
@> collateralToWithdraw = (collateralToWithdraw * 1050) / 1000;
return (collateralToWithdraw, debtAmount);
}

Solidity division truncates, so this calculation can lose precision and systematically round down. Since this value is then adjusted by a slippage buffer:

collateralToWithdraw = (collateralToWithdraw * 1050) / 1000;

any earlier truncation still affects the final result. With different token decimals (e.g., 6 vs 18) and price feeds with 8 decimals, rounding error can become material.

Impact:
Medium. Incorrect estimation of collateral to withdraw can lead to:

  • Withdrawing too little collateral → swap yields insufficient borrow token → unwind flow reverts or fails to fully repay debt.

  • Withdrawing too much collateral → unnecessarily reduces remaining collateral / worsens position outcomes.

Recommended Mitigation:
Use a full-precision mulDiv approach to reduce truncation and control rounding direction (often round up is safer here to ensure enough collateral is withdrawn).

+ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
collateralToWithdraw =
- (debtTokenPrice * debtAmount * 10 ** IERC20(_collateralToken).decimals())
- / (collateralTokenPrice * 10 ** IERC20(_borrowToken).decimals());
+ Math.mulDiv(
+ debtTokenPrice * debtAmount,
+ 10 ** IERC20(_collateralToken).decimals(),
+ collateralTokenPrice * (10 ** IERC20(_borrowToken).decimals()),
+ Math.Rounding.Ceil
+ );

This minimizes precision loss and makes unwind calculations more reliable across token decimal configurations.

Support

FAQs

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

Give us feedback!