Algo Ssstablecoinsss

AI First Flight #2
Beginner FriendlyDeFi
EXP
View results
Submission Details
Severity: high
Valid

Precision Mismatch in Health Factor Validation Affects WBTC Collateral

Root + Impact

Description

  • The health factor verification logic within _revert_if_health_factor_is_broken fails to account for token-specific decimal precision differences between WETH (18 decimals) and WBTC (8 decimals). The hardcoded threshold MIN_HEALTH_FACTOR = 10^18 creates a precision mismatch that artificially inflates WBTC health factor calculations

The current implementation applies a uniform health factor check across all collateral types:

@internal
def _revert_if_health_factor_is_broken(user: address):
user_health_factor: uint256 = self._health_factor(user)
assert (
user_health_factor >= MIN_HEALTH_FACTOR
), "DSCEngine__BreaksHealthFactor"

Since WBTC uses 8 decimals (Satoshi units) versus WETH's 18 decimals, the health factor for WBTC positions becomes inflated by a factor of 10101010. This decimal mismatch means WBTC collateral health factors are calculated incorrectly, allowing positions that should fail the health check to pass validation.


Risk

Users can maintain undercollateralized WBTC positions that bypass liquidation thresholds. The protocol incorrectly evaluates WBTC-backed positions as healthier than they actually are, exposing the system to insolvency risk during price volatility

Proof of Concept

N/A

Recommended Mitigation

Implement collateral-specific health factor thresholds that normalize for decimal precision:

@internal
def _revert_if_health_factor_is_broken(user: address):
user_health_factor: uint256 = self._health_factor(user)
normalized_threshold: uint256 = MIN_HEALTH_FACTOR
# Adjust threshold for WBTC's 8-decimal precision
if self._is_wbtc_collateral(user):
normalized_threshold = MIN_HEALTH_FACTOR * 10**10
assert user_health_factor >= normalized_threshold, "DSCEngine__BreaksHealthFactor"
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 1 day ago
Submission Judgement Published
Validated
Assigned finding tags:

[H-01] In the function \_revert_if_health_factor_is_broken constatnt variable MIN_HEALTH_FACTOR is only for WETH.

## Description The `_revert_if_health_factor_is_broken` function is responsible for ensuring that a user's health factor meets the minimum required standard. There is only implementation for WETH. ## Vulnerability Details In the function, there is only implementation for WETH. ```Solidity @internal def _revert_if_health_factor_is_broken(user: address): user_health_factor: uint256 = self._health_factor(user) assert ( user_health_factor >= MIN_HEALTH_FACTOR ), "DSCEngine__BreaksHealthFactor" ``` Value of the `MIN_HEALTH_FACTOR=10^18`is higher than the Satoshi factor which is 10^8. As a result, for WBTC, the `user_health_factor` can be inflated to more than 101010^{10} times its normal value. ## Impact Bigger value of MIN_HEALTH_FACTOR for WBTC allows on bigger value of `user_health_factor`and wrong value when function should revert. ## Recommendations Add MIN_HEALTH_FACTOR also for WBTC. ```Solidity @internal def _revert_if_health_factor_is_broken(user: address): user_health_factor: uint256 = self._health_factor(user) # Check if the user's token is WBTC and adjust health factor accordingly if user_health_factor >= (MIN_HEALTH_FACTOR * 10**10): # If user health factor is higher due to WBTC precision, still ensure it meets the minimum assert user_health_factor >= MIN_HEALTH_FACTOR, "DSCEngine__BreaksHealthFactor" else: assert user_health_factor >= MIN_HEALTH_FACTOR, "DSCEngine__BreaksHealthFactor" ```

Support

FAQs

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

Give us feedback!