Algo Ssstablecoinsss

AI First Flight #2
Beginner FriendlyDeFi
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Integer-division precision loss in the health-factor and token-amount math lets dust positions round in the wrong party's favor

Integer-division precision loss in health-factor and token-amount math lets dust positions and rounding favor the wrong party

Description

Both the health-factor calculation and the USD-to-token conversion perform integer division that truncates toward zero, with the divisions ordered so that small positions lose precision.

# dsc_engine.vy:326-329 (_calculate_health_factor)
collateral_adjusted_for_threshold: uint256 = (
collateral_value_in_usd * LIQUIDATION_THRESHOLD
) // LIQUIDATION_PRECISION # @> truncates before the *1e18 scaling
# dsc_engine.vy:360-364 (_get_token_amount_from_usd)
return (
(usd_amount_in_wei * PRECISION) // (
convert(price, uint256) * ADDITIONAL_FEED_PRECISION
) # @> floor division, dust rounds to 0
)

_get_token_amount_from_usd floors the result, so a liquidator covering a tiny debt can receive 0 collateral, and the threshold multiply-then-divide loses up to LIQUIDATION_PRECISION-1 of value per position.

Risk

Likelihood:
Low. The error is bounded to wei-scale dust for normal magnitudes; it only becomes material with very small amounts or very high-priced collateral.

Impact:
Low. Rounding can let a borrower hold a few wei of unbacked DSC or cause a liquidator to receive slightly less collateral than owed. No large-scale theft, but it erodes the strict invariant and can leave non-zero un-liquidatable dust debt.

Proof of Concept

Convert a sub-price USD amount and observe truncation to zero.

# price = 2000e8, ADDITIONAL_FEED_PRECISION = 1e10
# _get_token_amount_from_usd(weth, 1) = (1 * 1e18) // (2000e8 * 1e10) = 0
assert engine.get_token_amount_from_usd(weth, 1) == 0 # dust debt yields zero collateral

Recommended Mitigation

Multiply before dividing and/or document the rounding direction so it always favors the protocol.

- collateral_adjusted_for_threshold: uint256 = (
- collateral_value_in_usd * LIQUIDATION_THRESHOLD
- ) // LIQUIDATION_PRECISION
- return (collateral_adjusted_for_threshold * (10**18)) // total_dsc_minted
+ return (
+ collateral_value_in_usd * LIQUIDATION_THRESHOLD * (10**18)
+ ) // (LIQUIDATION_PRECISION * total_dsc_minted)
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 5 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!