The _mint_dsc internal function in dsc_engine.vy updates the user's debt state (user_to_dsc_minted) before executing the external call to DSC.mint(). Because the success of the extcall is not verified, if the minting operation fails, the user's debt is permanently increased without them receiving any DSC tokens.
In the _mint_dsc function, the protocol updates the accounting state and then attempts to mint the tokens:
In Vyper, extcall does not automatically revert the transaction if the external call fails; it simply returns False. If DSC.mint() fails (due to a bug in the DSC contract, a paused state, or a malicious token implementation), the transaction will still succeed. However, self.user_to_dsc_minted[msg.sender] has already been increased.
This results in a severe accounting mismatch where the user owes debt to the protocol but never received the corresponding stablecoins.
Severity: High
Likelihood: Medium
Impact: High
If a user calls deposit_collateral_and_mint_dsc or mint_dsc and the underlying DSC.mint fails:
The user's collateral remains locked in the engine.
The user's debt (user_to_dsc_minted) increases.
The user receives 0 DSC tokens.
This leads to a direct loss of funds and borrowing power for the user, as they are now in debt for tokens they do not possess. It also breaks the fundamental invariant of the stablecoin system (1 DSC debt = 1 DSC in circulation).
Add this test to tests/test_dsc_engine.py:
Run: mox test -k test_mint_dsc_fails_but_debt_increases
Expected Output:
Always verify the success of external calls in Vyper using extcall return values, or use the raw_call with revert_on_failure=True (though extcall is preferred for type safety).
Update _mint_dsc to check the return value:
Why This Works:
By checking the success boolean returned by extcall, the function will explicitly revert if the minting fails, preventing the state update and ensuring the user is never left with debt without the corresponding tokens.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.