Algo Ssstablecoinsss

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

Unchecked Return Value on DSC.mint Allows State/Balance Desync

Unchecked Return Value on DSC.mint Allows State/Balance Desync

Description

  • When a user mints DSC, the engine increments their user_to_dsc_minted balance and then calls DSC.mint to actually issue the tokens.

  • The return value of DSC.mint is never checked. If the mint call fails silently, the protocol's internal accounting records the user as having minted DSC that was never actually issued — permanently corrupting the debt ledger.

@internal
def _mint_dsc(amount_dsc_to_mint: uint256):
assert amount_dsc_to_mint > 0, "DSCEngine__NeedsMoreThanZero"
self.user_to_dsc_minted[msg.sender] += amount_dsc_to_mint # @> state updated before external call
self._revert_if_health_factor_is_broken(msg.sender)
extcall DSC.mint(msg.sender, amount_dsc_to_mint) # @> return value not checked

Risk

Likelihood:

  • The DSC token contract reverts or returns false on mint failure (e.g. due to access control, pausing, or an ownership misconfiguration) — the engine records the debt without the user ever receiving tokens.

  • A future upgrade to the DSC token that introduces a mintable cap or role check causes silent failures that the engine cannot detect.

Impact:

  • The user's user_to_dsc_minted is inflated, making their health factor appear worse than it is — they may be wrongly liquidated.

  • The protocol's total debt accounting diverges from actual token supply, breaking the peg mechanism.

Proof of Concept

Users can become eligible for a liquidation they do not deserve

# 1. User deposits valid collateral
dsc_engine.deposit_collateral(weth.address, 10 * 10**18, sender=user)
# 2. DSC token contract has a bug or access issuemint silently fails or reverts
# but the extcall in Vyper without success check does not propagate the revert
# 3. user_to_dsc_minted[user] is now > 0, but user holds 0 DSC tokens
# 4. User's health factor is now degraded despite holding no DSC
health = dsc_engine.health_factor(user)
# health < MIN_HEALTH_FACTOR -> user is eligible for liquidation they don't deserve

Recommended Mitigation

Capture and assert the return value of the mint call:

@internal
def _mint_dsc(amount_dsc_to_mint: uint256):
assert amount_dsc_to_mint > 0, "DSCEngine__NeedsMoreThanZero"
self.user_to_dsc_minted[msg.sender] += amount_dsc_to_mint
self._revert_if_health_factor_is_broken(msg.sender)
- extcall DSC.mint(msg.sender, amount_dsc_to_mint)
+ success: bool = extcall DSC.mint(msg.sender, amount_dsc_to_mint)
+ assert success, "DSCEngine__MintFailed"
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 1 hour 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!