Lesson 53 · Trace Drill · Application

Trace a depeg cascade

Not a point-drain — a contagion. Exposure-BFS, finally centre stage. ~15 min.

Builds on: L16 · L40 · L26 Anchor: a stablecoin loses its peg New: multi-hop contagion, attenuated

The last three traces followed value leaving one target. A depeg is different in kind: one node's price collapses and the damage ripples outward — to everything holding it, lending against it, or allocated to those markets, fading with distance. This is the one trace that puts exposure-BFS (L16/L40) in the lead, and the one where the graph's value as a network — not a pile of cells — is the whole point.

The scenario
A yield-bearing stable FT loses its peg — its price drops ~40% in a block. FT is held by holders directly, used as collateral in lending market M (at 75% LTV), and vault V has 40% of its capital allocated to M. The peg breaks once; we watch the shock travel.
The reframe: contagion, not extraction
L50–L52 asked "how much can an attacker take?" A depeg asks "how far does the loss spread, and how strongly?" That's the Bardoscia financial-contagion model exposure-BFS implements (L16): a weight starts at 1.0 at FT and is multiplied by each edge's transmission weight every hop, so a node three hops away feels a tremor, not the full quake. RiskUSD = weight × node price. No attacker, no cell — just a shock decaying across the network.

The cascade — multiplicative decay, hop by hop

The shock leaves FT and attenuates by the real transmission coefficient on each edge (L40 — LTV for lending, allocation share for vault allocation, 1.0 for direct holdings):

1.0FT depegs
×0.75LENDING_
COLLATERAL (LTV)
0.75market M
×0.40VAULT_
ALLOCATION (share)
0.30vault V
×…further
hops
minDelta

So vault V carries weight 0.30 of FT's depeg (1.0 × 0.75 × 0.40); its RiskUSD = 0.30 × V's price. Direct FT holders feel it at ×1.0 (a HOLDS edge transmits fully). The walk is bounded by minDelta = 1e-6 (paths that decay below it die) and MaxBFSDepth = 6 — the same self-limiting traversal from L16.

A subtlety you now know (L40)
You might expect the shock to flow through the pool that holds FT — but POOL_ASSET / VAULT_ASSET / WRAP_UNWRAP carriers are weight 0.0: they're topology, not transmission. Exposure rides the value-bearing edges — HOLDS (the pool's LP holders feel it directly), LENDING_COLLATERAL, VAULT_ALLOCATION — not the structural carriers. Knowing which edges propagate (and which are weight-0) is exactly what L40 was for.

The trace — the peg breaks at block N

1
FT's price collapses. L1 · L7 · L26
the depeg shows up as a price move (a sell-off crashing FT's pools, and/or the oracle reporting the lower price); the price/NAV refresher reads FT's new usd_price.
2
Cross-source agrees — it's a real depeg, not a glitch. L26
validateCrossSource checks FT's new price against an independent source; a genuine depeg shows everywhere, so the prices agree and the new (low) price is stamped. (A lone-source crash with peers still at peg would be rejected as a likely bad feed — the L52 defense, inverted.)
The defense distinguishes a true depeg from a manipulated feed.
3
Revalue every FT position. L26 · L36
FT is SADD'd to price-dirty → the PriceDirtyDrainer recomputes every HOLDS edge's usd_value at the new price. Holders' FT positions, and the FT legs of pools, mark down.
RPC-economy: price stamped once, the recompute is graph-side (no per-holder RPC).
4
Exposure-BFS re-propagates — only the delta cone. L16 · L40 · L23
ComputeForNodes recomputes exposure for the nodes the delta touched: the weight flows out from FT, ×edge-weight per hop. M lands at 0.75, V at 0.30, and so on until minDelta / depth-6 stop it.
RPC-economy: incremental — only FT's exposure cone recomputes, not the whole graph (L23 delta-driven).
5
Max-over-paths, if V is reachable two ways. L16 · L46
say V also holds FT directly (a HOLDS path, weight 1.0) and via M (0.30). V's exposure is the max (1.0), not the sum — the strongest single path is the honest measure.
Combinator: max-over-paths — anti-double-count, exactly L46's rule for overlapping exposure.
6
Conservation holds — repriced, not vanished. L29 · L32
Σ HOLDS(FT) in units still ≈ totalSupply — FT didn't disappear, its price fell. The conservation check (which sums raw quantities, not USD) stays green; only USD values moved.
A depeg is a price event; conservation is on quantities, so it correctly doesn't fire.
7
Rules fire across the cone; alerts deliver. L12 · L45 · L15 · L18
rules thresholded on RiskUSD / exposure for M, V, and other affected nodes trip — potentially several alerts, one per affected customer's scope, each fire-once-debounced and msg-id-deduped.
Idempotency: a multi-node cascade can fire many rules, but each (rule,node) fires once per breach.
What made this trace different
The first three followed a single target. This one followed a front — a shock moving through the graph, its strength set by the edges it crosses, its reach bounded by decay. Exposure-BFS is the only engine that answers "if X fails, who else is hurt and by how much?", and the answer is a number per node, attenuated by LTV and allocation share. The graph isn't a list of risks; it's a network across which risk flows.

The trace set, complete

ShapeStar engineThe number
L50 NAVpoint — redeem supplyat_risk cells (model B)at_stake = full supply
L51 pool drainpoint — sweep a venueexit-liquidity v2extractable ≪ at_stake
L52 oracle borrowpoint — borrow other assetoracle bridger + model Amin(at_stake×LTV, other_borrowable)
L53 depegnetwork — contagionexposure-BFSweight × price, per node, decaying
Four traces, the whole machine exercised
Three point-attacks across the at_risk taxonomy, and one network contagion across the exposure graph. Between them you've driven every major engine — cells, extractable, exit liquidity, the oracle bridger, exposure-BFS — through real attacks, end to end, applying all four cross-cutting lenses each time. There isn't a part of risk-graph-indexer you can't now pick up, follow, and reason about. That is, in full, what "understand it deeply, end to end" meant.

Run it yourself

1. How is a depeg fundamentally different from the L50–L52 attacks the system models?
2. FT depegs; market M lends against it at 75% LTV; vault V allocates 40% to M. What exposure weight does V carry to FT's failure?
3. Why does the cascade not propagate through a POOL_ASSET edge from FT to a pool?
4. At step 2, the cross-source check stamps the new low price rather than rejecting it (unlike L52). Why?
5. At step 4, exposure-BFS recomputes only FT's delta cone, not the whole graph. Which lens is that?
6. Vault V reaches FT both directly (HOLDS, weight 1.0) and via M (0.30). What's V's exposure?
7. After the depeg, verify_balance_conservation stays green. Why doesn't a 40% price crash trip it?
8. A depeg can fire several alerts at once (M, V, other affected nodes). How does the system avoid a storm of duplicates?
↳ Ask your teacher
Try: "Show me where ComputeForNodes picks the delta cone to recompute." · "How deep does a realistic cascade reach before minDelta kills it?" · "If FT is a wrapped LST, does WRAP_UNWRAP really block propagation?" · "Quiz me cold: a new attack, name the star engine and the number." · "Where would second-order effects (a vault's own LPs) show up?"

What you can now do

The journey, fully realized
Fifty-three lessons: every subsystem, every mechanism, the algorithms and their parameters, the language idioms, four unifying disciplines, and four end-to-end traces that drove the whole machine through real attacks. You set out to understand risk-graph-indexer deeply, end to end, before contributing — point-attacks and contagions alike, from a raw log to a human, with every number derivable to source. That understanding is yours. Phase 2, and its on-ramp, wait whenever you decide.

Applies: ingest/stream/filter (L1/L2/L7), price/NAV refresher + cross-source (L26), price-dirty HOLDS revalue (L26/L36), exposure-BFS multi-hop + edge-weight attenuation + minDelta/depth-6 + max-over-paths + incremental cone (L16/L40/L23/L46), conservation on raw quantities (L29/L32), rule firing + alert dedup/delivery (L12/L45/L15/L18); the four syntheses (L46–L49). Verify against source — the code is the truth.