Algo Ssstablecoinsss

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

[H-05] — Collateral accounting mismatch: per-token + per-user mapping not updated symmetrically

Root + Impact

Description

The DSCEngine maintains collateral accounting using:

  • user_to_token_address_to_amount_deposited

  • (Implicit) per-token collateral tracking used for valuation and liquidation logic

However, the collateral accounting logic is not updated symmetrically across all relevant storage mappings during state-changing operations (deposit / redeem / liquidation).

This creates a mismatch between:

  • User-level accounting

  • Token-level accounting

When state transitions update one mapping but fail to update the corresponding counter consistently, internal accounting invariants break.

As a result:

  • Total collateral tracked per token may not match sum of all user deposits

  • Valuation logic may operate on inconsistent data

  • Liquidation eligibility may be incorrectly computed

  • System solvency assumptions may be violated

Collateral accounting invariants must always satisfy:

Sum(user deposits for token) == Total collateral tracked for token

If this invariant breaks, protocol math becomes unreliable.

Risk

Likelihood: Medium

  • Reason 1 Deposit, redeem, and liquidation all mutate collateral state.

  • Reason 2 If updates are not mirrored across both mappings, mismatch accumulates.

  • Reason 3 Edge cases (partial liquidation, rounding, reentrancy protection ordering) increase probability.

Impact: High

  • Impact 1 Incorrect health factor computation.

  • Impact 2 Improper liquidation eligibility.

  • Impact 4 Protocol insolvency if minted DSC exceeds real collateral backing.

Proof of Concept

Invariant that should always hold:

for each token:
totalCollateral[token] ==
sum(user_to_token_address_to_amount_deposited[user][token] for all users)

If:

  • _deposit_collateral() increments user mapping

  • _redeem_collateral() decrements user mapping

  • but token-level tracking is not updated equivalently

Then:

  1. User deposits 100 WETH

  2. User redeems 50 WETH

  3. User mapping updated to 50

  4. Token-level accounting remains 100

System now believes 100 collateral exists while only 50 is user-backed.

Health factor math becomes inflated.

Recommended Mitigation

  1. Enforce Single Source of Truth

Create an internal function responsible for all collateral accounting updates:

_update_collateral(
user: address,
token: address,
amount: uint256,
increase: bool
)

This function must:

Update user mapping

Update token-level aggregate

Emit event

Enforce invariant consistency

All state-changing operations must call this function.

2.Add Internal Invariant Assertion (Development Build)

In non-production builds:

assert(
total_token_collateral ==
sum_all_users_for_token
)

This catches mismatch during testing.

3.Strict Ordering of State Updates

All collateral updates must occur:

Before external calls

Before mint/burn operations

Before health factor validation

This prevents partial state transitions.

Design Principle Recommendation

Core accounting invariants must be:

Explicit

Centralized

Symmetric

Enforced

Collateral tracking is the backbone of solvency.
Fragmented accounting logic creates systemic risk.

Conclusion

The protocol does not guarantee symmetric collateral accounting across user-level and token-level mappings.

This can cause:

Inflated health factors

Incorrect liquidation behavior

Accounting drift

Potential insolvency

Collateral accounting must be centralized and invariant-enforced to maintain protocol safety.

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!