Algo Ssstablecoinsss

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

[H-01] Missing Return Value Check on DSC mint() Allows Silent Minting Failures

Root + Impact

Description

  • The _mint_dsc() function calls extcall DSC.mint() but does not check the return value. The comment explicitly acknowledges this with "Note, we are not checking success here".

  • When the mint fails silently (returns false instead of reverting), the user's user_to_dsc_minted balance is incremented but no tokens are actually minted, creating an accounting mismatch that breaks the protocol's invariants and could lead to insolvency.

// Root cause in the codebase with @> marks to highlight the relevant section
@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)
@> # Note, we are not checking success here
@> extcall DSC.mint(msg.sender, amount_dsc_to_mint)

Risk

Likelihood: Medium

  • Reason 1 // Depends on DSC token implementation behavior

  • Reason 2 // Some ERC-20 implementations return false on failure instead of reverting

Impact: High

  • Impact 1 // User's debt is recorded but no tokens received

  • Impact 2 // Protocol accounting becomes inconsistent

  • Impact3 // User cannot burn tokens they don't have to clear their debt

  • Impact 4 // Collateral becomes permanently locked

Proof of Concept

The following scenario demonstrates how a user can have debt recorded without receiving tokens. When the DSC mint function returns false instead of reverting on failure, the user's collateral becomes trapped since they cannot burn DSC tokens they never received to free their collateral.

def test_mint_failure_locks_collateral():
# User deposits collateral
with boa.env.prank(user):
weth.approve(dsce, COLLATERAL_AMOUNT)
dsce.deposit_collateral(weth, COLLATERAL_AMOUNT)
# If DSC.mint() fails silently (returns false)
# user_to_dsc_minted is incremented
# but user receives no tokens
dsce.mint_dsc(AMOUNT_TO_MINT)
# User has recorded debt but no tokens
dsc_minted, _ = dsce.get_account_information(user)
assert dsc_minted == AMOUNT_TO_MINT # Debt recorded
assert dsc.balanceOf(user) == 0 # No tokens received
# User cannot redeem collateral - health factor broken
# User cannot burn DSC - they have none
# Collateral is permanently locked

Recommended Mitigation

Check the return value of the mint call and revert if it fails. This ensures atomic execution where either both the accounting update and token mint succeed, or the entire transaction reverts with no state changes.

@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)
- # Note, we are not checking success here
- 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 3 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!