<!--
Sitemap:
- [Welcome to River](/index)
- [Asset-Backed Finance Primer](/concepts/finance-primer)
- [River for Lenders](/lenders/introduction)
- [Depositing](/lenders/depositing)
- [Earning: the Coupon](/lenders/earning)
- [The Accumulating Wrapper](/lenders/wrapper)
- [Withdrawals & Exits](/lenders/withdrawals)
- [Losses & Impairments](/lenders/losses)
- [FAQ](/lenders/faq)
- [Integrate with River](/integrate/get-started)
- [Wrapper Integration](/integrate/wrapper)
- [Class Token Integration](/integrate/class-token)
- [Contract Addresses](/integrate/addresses)
- [Protocol Architecture](/architecture)
- [Actors: Roles & Permissions](/technical/actors)
- [Proxies & Upgradeability](/technical/proxies)
- [Strategies & Reporters](/technical/strategies)
- [Glossary](/concepts/glossary)
- [Dual NAV & Exchange Rates](/accounting/dual-nav)
- [Settlement & Conservation](/accounting/settlement)
- [The Coupon Ledger](/accounting/coupon-ledger)
- [Wrapper Accounting](/accounting/wrapper)
- [Accounting Examples](/accounting/examples)
- [The Tiered Waterfall](/waterfall/)
- [Waterfall Scenarios](/waterfall/scenarios)
- [Security Model](/security)
- [Protocol Invariants](/technical/invariants)
- [List of Assumptions](/technical/assumptions)
- [External Entry Points](/technical/entry-points)
- [Governance](/governance)
- [Contract Reference](/reference/contracts)
- [River Engineering Standards](/reference/engineering-standards)
-->

# Waterfall Scenarios

This page gives concrete examples for the tiered waterfall. The test suite covers these behaviors in
`test/unit/TieredWaterfall.t.sol`.

## How To Read These Scenarios

`TieredWaterfall` handles **losses and recoveries**. Interest is handled entirely **off-chain**:
the servicer collects loan interest off-chain and pays a cash coupon on-chain through
`DistributingClassToken.accrue()` / `fund()` (a two-layer accrue-then-fund model). On-chain class
NAV tracks **principal at par** and moves DOWN on a credit loss and back UP on a recovery.

The Structure hands the waterfall two decomposed flows per settlement (`Flows`):

| Field | Meaning |
| --- | --- |
| `impairment` | Signed credit signal. Negative is a newly reported loss (consumed junior-tier first and recorded so a later recovery can reverse it). Positive is a recovery of previously absorbed loss (restored senior-tier first, capped per class). |
| `income` | Non-credit P\&L. In normal operation this is **zero**, because interest is off-chain. Positive income is purely residual and routes to the most junior tier; negative income is a non-credit value drop consumed junior-tier first. Recovery beyond the absorbed-loss ledger folds into `income`. |

Classes are grouped into contiguous seniority **tiers** by `tierSizes`, ordered most senior first (index 0
is most senior, matching the Structure's class registration order). Classes in the same tier are
**pari-passu**: a loss or recovery hitting that tier is split pro-rata among its classes — by available NAV
for losses, by absorbed loss for recoveries. Tiers are sequential: losses consume the most junior tier to
exhaustion before touching a more senior one; recoveries restore the most senior tier first. A tier of
size 1 degenerates to strict-sequential behavior.

Unless a scenario says otherwise, use this setup — two pari-passu seniors over a single residual junior,
i.e. `tierSizes = [2, 1]`:

| Class | Tier | Initial NAV | Role |
| --- | --- | --- | --- |
| SENIOR-A | Senior (pari-passu) | 100.00 | Principal, restored senior-first |
| SENIOR-B | Senior (pari-passu) | 100.00 | Principal, restored senior-first |
| JUNIOR | Junior (residual) | 50.00 | First-loss and residual claim |

Amounts are in deal-asset units. There is no timestamp or owed-debt state in the waterfall — nothing
accrues here. The only persisted state is the per-class absorbed-loss ledger (`abi.encode(uint256[]
absorbedLossPerClass)`), threaded through `waterfallState` bytes by the Structure.

## Losses

### L1: Loss Inside The Junior Cushion

Rule shown: losses consume the most junior tier first.

Event: `impairment = -30.00`.

| Class | NAV before | Absorbs | NAV after |
| --- | --- | --- | --- |
| SENIOR-A | 100.00 | 0.00 | 100.00 |
| SENIOR-B | 100.00 | 0.00 | 100.00 |
| JUNIOR | 50.00 | -30.00 | 20.00 |
| Total | 250.00 | -30.00 | 220.00 |

The absorbed-loss ledger becomes `[0, 0, 30]`.

### L2: Loss Spills To The Senior Tier, Pari-Passu

Rule shown: once the junior tier is exhausted, the remaining loss hits the senior tier and is split
pro-rata by available NAV among its pari-passu classes.

Event: `impairment = -90.00`. Junior (50.00) is fully wiped; the remaining 40.00 splits equally across the
two equal seniors.

| Class | NAV before | Absorbs | NAV after |
| --- | --- | --- | --- |
| SENIOR-A | 100.00 | -20.00 | 80.00 |
| SENIOR-B | 100.00 | -20.00 | 80.00 |
| JUNIOR | 50.00 | -50.00 | 0.00 |
| Total | 250.00 | -90.00 | 160.00 |

The ledger becomes `[20, 20, 50]`.

### L3: Uneven Seniors Split Pro-Rata By NAV

Rule shown: within a tier the split is pro-rata by available NAV.

Setup: seniors at 100.00 / 300.00, junior at 50.00. Event: `impairment = -130.00`. Junior (50.00) is wiped;
the remaining 80.00 splits 1:3.

| Class | NAV before | Absorbs | NAV after |
| --- | --- | --- | --- |
| SENIOR-A | 100.00 | -20.00 | 80.00 |
| SENIOR-B | 300.00 | -60.00 | 240.00 |
| JUNIOR | 50.00 | -50.00 | 0.00 |
| Total | 450.00 | -130.00 | 320.00 |

### L4: Loss Beyond Total NAV

Rule shown: class NAV cannot go negative.

Event: `impairment` of -251.00 against total NAV of 250.00. Settlement reverts with `LossExceedsNav`.

## Recoveries

A recovery is a positive `impairment`. It restores previously absorbed loss most-senior-tier first,
pro-rata by absorbed loss within a tier, and capped per class by what that class actually absorbed. Any
recovery beyond the recorded ledger folds into `income` (residual) and is routed to the junior tier.

### R1: Recovery Restores The Senior Tier First

Continuing from L2 — ledger `[20, 20, 50]`, NAVs at 80.00 / 80.00 / 0.00.

Event: `impairment = +40.00`. This fully restores the senior tier pari-passu while the junior
still waits for recovery.

| Class | NAV before | Receives | NAV after | Ledger after |
| --- | --- | --- | --- | --- |
| SENIOR-A | 80.00 | +20.00 | 100.00 | 0.00 |
| SENIOR-B | 80.00 | +20.00 | 100.00 | 0.00 |
| JUNIOR | 0.00 | 0.00 | 0.00 | 50.00 |
| Total | 160.00 | +40.00 | 200.00 | — |

The junior still owns 50.00 of unrestored absorbed loss.

### R2: Recovery Spills To Junior, Then Surplus Is Residual Income

Continuing from L2 — ledger `[20, 20, 50]` (total absorbed 90.00), NAVs at 80.00 / 80.00 / 0.00.

Event: `impairment = +100.00`. The first 90.00 restores the entire ledger (seniors 40.00, junior 50.00);
the surplus 10.00 is beyond the ledger, so it folds into income and routes to the junior (residual) tier.

| Class | NAV before | Receives | NAV after |
| --- | --- | --- | --- |
| SENIOR-A | 80.00 | +20.00 | 100.00 |
| SENIOR-B | 80.00 | +20.00 | 100.00 |
| JUNIOR | 0.00 | +60.00 | 60.00 |
| Total | 160.00 | +100.00 | 260.00 |

Junior receives its 50.00 restoration plus the entire 10.00 residual surplus.

### R3: Wiped Junior Still Owns The Residual

Rule shown: a zero-NAV junior class still holds the residual position and can recover.

The junior tier is wiped (NAV 0.00) but its absorbed loss is recorded in the ledger. The senior tier is
restored first; once the ledger clears, any further recovery surplus is income that routes to the junior
tier even though its starting NAV was zero — as shown by the +60.00 junior delta in R2.

## Income

Interest is off-chain, so `income` is **zero** in normal operation. The income branch exists only to
conserve stray non-credit P\&L and to absorb recovery surplus beyond the ledger.

### I1: Positive Income Is Pure Residual

Rule shown: with no on-chain coupon, positive income is the residual claim and routes to the most junior
tier (split pro-rata by NAV within that tier; here a single class).

Event: `income = +30.00`, `impairment = 0`.

| Class | NAV before | Receives | NAV after |
| --- | --- | --- | --- |
| SENIOR-A | 100.00 | 0.00 | 100.00 |
| SENIOR-B | 100.00 | 0.00 | 100.00 |
| JUNIOR | 50.00 | +30.00 | 80.00 |
| Total | 250.00 | +30.00 | 280.00 |

The seniors get nothing: there is no cost of capital to pay, so the whole amount is junior's residual.

### I2: Negative Income Is A Non-Credit Drop

Rule shown: negative income is consumed junior-tier first, like a loss, and stays outside the
absorbed-loss ledger. Later recoveries reverse credit charge-offs only.

Event: `income = -30.00`, `impairment = 0`. The junior absorbs the full 30.00; the ledger is unchanged.

## The Off-Chain Coupon

Interest follows the coupon path:

1. The servicer collects loan interest off-chain.
2. A keeper (`KEEPER_ROLE`) calls `DistributingClassToken.accrue(amount)` to record the entitlement — this
   raises the per-share `accIndex` by `amount * RAY / supply` (RAY = 1e27, rounding down; dust stays in the
   contract) and moves no cash.
3. Later (e.g. monthly) the keeper calls `fund(cash)` to back the accrued interval, pricing it at
   `rho = min(1, cash/intervalAccrued)` — a shortfall haircuts that interval pro-rata. Only funded coupon is
   claimable, settled per holder in `_update` before any balance change, so coupon never rides along with a
   transfer.

Because principal NAV is tracked on-chain and coupon is a separate cash accumulator, a holder's total return
is `principal NAV (par, less any unrecovered loss) + accrued coupon`. The waterfall governs only the first
term.

## Caveat

### N1: Netting Simultaneous Recovery And Loss

The Structure decomposes each strategy's value change into `income` and `impairment` and nets them per
settlement before calling the waterfall.

If one settlement reports both a +10.00 recovery and a -10.00 new loss with no prior absorbed loss, the net
credit signal is 0.00 and no class NAV moves. The operational rule that keeps deltas clean: settle once per
pricing event, so one attestation is approximately one economic event.

## A Full Credit Cycle

Three settlements over the life of the deal: a loss, a partial recovery, then a full recovery with surplus.
Setup is the default `[2, 1]` layout (SENIOR-A 100.00, SENIOR-B 100.00, JUNIOR 50.00). Coupon
stays off-chain throughout this example.

| Event | `impairment` | SENIOR-A NAV | SENIOR-B NAV | JUNIOR NAV | Ledger after |
| --- | --- | --- | --- | --- | --- |
| Deal funds | — | 100.00 | 100.00 | 50.00 | \[0, 0, 0] |
| Loss | -90.00 | 80.00 | 80.00 | 0.00 | \[20, 20, 50] |
| Partial recovery | +40.00 | 100.00 | 100.00 | 0.00 | \[0, 0, 50] |
| Full recovery | +60.00 | 100.00 | 100.00 | 60.00 | \[0, 0, 0] |

Conservation check: 250.00 - 90.00 + 40.00 + 60.00 = 260.00 = 100.00 + 100.00 + 60.00.

The headline: the junior tier absorbed the loss first, the senior tier was restored first, and once the
absorbed-loss ledger cleared the residual surplus (10.00 on the final +60.00) went to the junior. No
interest crossed the waterfall — that lived in the off-chain coupon the whole time.
