Algo Ssstablecoinsss

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

Reentrancy Allows Minting DSC Without Real Collateral

Root + Impact

Description

  • When users deposit collateral, the protocol should first securely receive the collateral tokens and only then update internal accounting.
    This ensures DSC can only be minted against collateral that has actually been transferred into the protocol.

  • The contract updates user collateral balances before performing the external ERC20 transfer.
    Because ERC20 transfers are external calls, a malicious token can reenter the protocol during execution and mint DSC while the system already believes collateral has been deposited, even though the transfer has not completed.

@internal
def _deposit_collateral(
token_collateral_address: address, amount_collateral: uint256
):
assert amount_collateral > 0
# @> STATE UPDATED BEFORE EXTERNAL CALL
self.user_to_token_address_to_amount_deposited[msg.sender][
token_collateral_address
] += amount_collateral
# @> EXTERNAL INTERACTION (REENTRANCY POINT)
success: bool = extcall IERC20(token_collateral_address).transferFrom(
msg.sender, self, amount_collateral
)

This breaks the Checks-Effects-Interactions pattern and allows collateral accounting to be manipulated during reentrancy.

Risk

Likelihood:

  • Occurs when a collateral token performs callbacks during transferFrom execution.

  • Occurs when a non-standard or upgradeable ERC20 token is included in the collateral basket.

Impact:

  • Attacker can mint DSC backed by collateral that was never transferred.

  • Protocol collateralization invariant is broken, potentially causing insolvency and stablecoin depeg.

Proof of Concept

// Conceptual attack flow
1. Attacker deploys malicious ERC20 token with custom transferFrom().
2. Token is accepted as collateral.
3. Attacker calls:
deposit_collateral(maliciousToken, 1000e18)
4. During transferFrom(), token executes callback:
DSCEngine.mint_dsc(maxAmount);
5. Because collateral balance was already increased,
health factor check passes.
6. DSC is minted even though collateral transfer
has not completed or never actually occurs.

The protocol trusts internal accounting instead of verifying that tokens were successfully received before allowing minting. Reentrancy allows the attacker to exploit this temporary inconsistent state.

Recommended Mitigation

Follow Checks-Effects-Interactions ordering.

@internal
def _deposit_collateral(token_collateral_address: address, amount_collateral: uint256):
- self.user_to_token_address_to_amount_deposited[msg.sender][token_collateral_address] += amount_collateral
success: bool = extcall IERC20(token_collateral_address).transferFrom(
msg.sender, self, amount_collateral
)
assert success
+ self.user_to_token_address_to_amount_deposited[msg.sender][token_collateral_address] += amount_collateral

Additional hardening:

+ add nonReentrant protection
+ optionally verify token balance delta after transfer
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 3 days 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!