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:
If this invariant breaks, protocol math becomes unreliable.
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.
Invariant that should always hold:
If:
_deposit_collateral() increments user mapping
_redeem_collateral() decrements user mapping
but token-level tracking is not updated equivalently
Then:
User deposits 100 WETH
User redeems 50 WETH
User mapping updated to 50
Token-level accounting remains 100
System now believes 100 collateral exists while only 50 is user-backed.
Health factor math becomes inflated.
Enforce Single Source of Truth
Create an internal function responsible for all collateral accounting updates:
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:
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.
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.
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.