# Fletch — Litepaper

*Dividend yield-stripping for tokenized equities on Robinhood Chain.*

> This document mirrors the shipped contracts. It is a technical litepaper, not
> investment advice.

---

## 1. One-liner

**Pendle for tokenized equities.** Fletch splits Robinhood Chain Stock Tokens into
**Principal Tokens (PT)** and **Yield Tokens (YT)**, creating fixed-discount equity
exposure and the first tradeable on-chain market for dividend streams — *on-chain
dividend futures*. The number this protocol uniquely creates is the **implied
dividend yield**.

### At a glance

| | |
|---|---|
| **Chain** | Robinhood Chain (Arbitrum Orbit L2, ETH gas) |
| **Underlyings** | Robinhood Stock Tokens — ERC-8056 (KO, SPY, SCHD, QQQ) |
| **Products** | PT (fixed-discount principal) · YT (dividend futures) |
| **Settlement** | European — value settles at maturity |
| **Core invariant** | `R_pt + R_yt = R` — no liquidations, no bad debt |
| **Redemption depends on** | the dividend index `D(T)` only, never price |
| **Oracle** | Chainlink (heuristics / display only) |
| **Fees** | None in v1 |
| **Governance** | Guardian multisig (Safe 2/3); `$FLETCH` is future work |

---

## 2. The asset: ERC-8056 Stock Tokens

Robinhood Stock Tokens are ERC-20s (18 decimals) issued by Robinhood Assets
(Jersey) Limited, backed 1:1 by custodied shares. They **do not pay cash
dividends**. Instead, corporate actions are reflected through an on-chain
multiplier — the ERC-8056 *Scaled UI Amount Extension*:

- `uiMultiplier()` — current multiplier (18 decimals, `1e18 == 1.0`). Underlying
  shares = `rawBalance × uiMultiplier ÷ 1e18`.
- **Raw balances and `totalSupply` never change on a corporate action.** Only the
  multiplier moves.
- `newUIMultiplier()` / `effectiveAt()` — scheduled changes are readable *before*
  they take effect.
- Events: `UIMultiplierUpdated(old, new, effectiveAt)`, `TransferWithScaledUI(...)`.

The multiplier moves for **both dividends and splits**. A Stock Token is therefore
structurally a yield-accruing wrapper (like wstETH): dividend yield = multiplier
growth. That is exactly the asset shape Pendle-style splitting was designed for.

Distinguishing dividends from splits is the core engineering problem — see §5.

---

## 3. Core mechanic

A **Series** is a pair `(underlying Stock Token, maturity)`, e.g.
`PT-KO-DEC2026` / `YT-KO-DEC2026`.

- **Deposit** `R` raw Stock Tokens before maturity → mint `R` **PT** and `R` **YT**.
- **PT** — *fixed-discount equity exposure*. At maturity, redeems for the raw
  tokens representing the same **split-adjusted, dividend-stripped** share count as
  deposited. Trades at a discount to spot; the discount is the implied dividend yield.
- **YT** — *leveraged dividend exposure / dividend futures*. At maturity, redeems
  for the raw tokens attributable to dividend-driven multiplier growth over the term.
- **Settlement** is European for the MVP: all value settles at maturity. YT trades
  freely before maturity. (Continuous per-event YT claiming is Phase 2.)

---

## 4. Accounting

### 4.1 The multiplier decomposition

Let the classifier track, per underlying, two cumulative indices in WAD
(`1e18 == 1.0`), both starting at `1.0` when the underlying is registered:

- `D(t)` — cumulative **dividend** growth factor.
- `K(t)` — cumulative **split** factor.

Each `UIMultiplierUpdated` event multiplies exactly one of them by the change ratio
`new / old`, depending on its classification.

The token multiplier itself is `m(t) = m₀ · D̂(t) · K̂(t)` where `D̂`, `K̂` are the
growth since some reference. Splits change what each raw token is *worth* but not
how many raw tokens you are entitled to, so **splits pass through to PT and YT
identically and never enter the vault's split math**. Only dividends redistribute
value between PT and YT.

### 4.2 Series-relative dividend growth

A series snapshots the dividend index at creation, `D_create`. At any time:

```
D_T = D_now × 1e18 / D_create        (WAD, floored at 1.0)
```

At maturity this is frozen. `D_T` is the total dividend growth attributable to the
series term.

### 4.3 Mint and redeem

Depositing `R` raw tokens mints `R` PT and `R` YT (1:1). Because both legs are
always minted and burned together before maturity, the vault's raw balance always
equals the PT (and YT) supply, so **paired redemption is exact**:

```
redeemBeforeMaturity(a):  burn a PT + a YT  →  a raw            (always available)
```

At settlement, the fixed raw pool `R_total` is split **once**:

```
principalRaw = shares × 1e18 / D_T
yieldRaw     = R_total − principalRaw
```

and each leg redeems pro-rata at a uniform rate:

```
redeemPT(a)  →  a × 1e18 / D_T          =  a / D_T
redeemYT(a)  →  a × (D_T − 1e18) / D_T  =  a × (1 − 1/D_T)
```

These are exactly the brief's headline formulas `R_pt = R/D(T)` and
`R_yt = R(1 − 1/D(T))`.

### 4.4 The solvency invariant

For any amount `a`, `redeemPT(a) + redeemYT(a) = a` (up to 1 wei of floor rounding),
and `principalRaw + yieldRaw = R_total`. **The vault can never be insolvent** — there
are no liquidations and no bad debt is possible. This is fuzz- and
invariant-tested (`test/Invariant.t.sol`, 8192-call stateful runs).

### 4.5 Worked example

Deposit `R = 100`. Over the term: `+2%` dividend, `2:1` split, `+3%` dividend.

- `D_T = 1.02 × 1.03 = 1.0506` (the split does **not** enter `D`; it lives in `K`).
- Final token multiplier `= 1.02 × 2 × 1.03 = 2.1012`.
- `R_pt = 100 / 1.0506 = 95.18` raw → `95.18 × 2.1012 = 200` shares — exactly the
  original 100 shares scaled by the `2×` split, dividend stripped.
- `R_yt = 100 × (1 − 1/1.0506) = 4.82` raw → the dividend-attributable shares.
- `R_pt + R_yt = 100`. ✔

### 4.6 Fungibility note (MVP simplification)

PT and YT are fungible ERC-20s, and `D_T` is referenced from **series creation**
(the deposit epoch is the series itself). A mid-term depositor therefore receives a
PT/YT split reflecting the series' cumulative dividends. Because both legs are
minted 1:1 and the pair is always worth the deposit, the mint is net-neutral and
arbitrage-free; a depositor simply trades to their desired exposure. Per-deposit
yield indexing (à la Sense/Pendle) is a Phase-2 refinement; it is not required for
solvency, which holds unconditionally.

### 4.7 Convexity quirk (a feature)

Dividends reinvest at market price, so YT receives *share-fractions*, not dollars.
Falling prices → the same dividend buys more shares → YT benefits slightly. This is
intentional and documented.

---

## 5. The classifier (core moat, highest risk)

Every `UIMultiplierUpdated` must be attributed to **DIVIDEND** (grows `D`) or
**SPLIT** (grows `K`). A split mis-booked as a dividend would inflate `D_T` and
transfer principal value from PT holders to YT holders. Mitigations:

1. **Optimistic keeper.** Ex-dividend calendars and split announcements are public,
   and pending multiplier changes are readable in advance via `newUIMultiplier()` /
   `effectiveAt()`. A keeper posts the classification.
2. **On-chain heuristic sanity check.** Auto-flags obviously wrong classifications
   for guardian co-sign:
   - A move `> 5%` labelled *dividend* (dividends are small) → co-sign required.
   - A move `< 1%` labelled *split* (splits are chunky) → co-sign required.
3. **Dispute window.** A classification can only be applied after **24h**, during
   which the guardian multisig can override the kind or reject it.
4. **Fail-safe pause.** While a live multiplier change is **unattributed** (the
   token's multiplier differs from the last applied value), **deposits pause** for
   that underlying — guaranteeing the dividend index is never stale at deposit time.
   Paired PT+YT redemption is *never* blocked.
5. **Unhandleable events** (merger, spinoff, delisting, ticker change): the guardian
   calls `emergencySettle()`, freezing `D/K` at the last-known value and opening
   PT/YT redemption immediately.

The split-as-dividend attack and its guardian recovery are proven in
`test/Classifier.t.sol::test_SplitAsDividend_CaughtByHeuristicAndGuardian`.

---

## 6. Oracles

- Read Chainlink via `latestRoundData()` (`AggregatorV3Interface`) through the feed
  proxy.
- **The feed price already includes the multiplier — never multiply again.**
  Per-share price is `feedPrice × 1e18 / uiMultiplier`, applied *exactly once*
  (`test/Oracle.t.sol::test_PerSharePrice_DividesMultiplierExactlyOnce`).
- **Staleness** is weekend-aware: US equity feeds are stale-but-valid over
  weekends, so a 72h tolerance applies Friday-close through Sunday; a tighter
  per-asset heartbeat applies on weekdays.
- **L2 sequencer uptime** (Arbitrum-style) is checked, with a grace period after
  the sequencer recovers.
- Oracles feed only the classifier heuristics, the front-end, and (Phase 2) the
  AMM. **Core redemption math depends only on `D_T`, never on price.** This keeps
  the trust surface minimal.

---

## 7. Contract architecture

```
contracts/
├── core/
│   ├── SeriesFactory.sol      deploys PT/YT + vault per (underlying, maturity), CREATE2
│   ├── SeriesVault.sol        holds raw tokens; mint/redeem/settlement accounting
│   ├── PrincipalToken.sol     PT ERC-20 (vault-gated mint/burn)
│   └── YieldToken.sol         YT ERC-20 (vault-gated mint/burn)
├── classifier/
│   ├── CorporateActionOracle.sol   maintains D and K; keeper + dispute + heuristics
│   └── interfaces/{IERC8056, ICorporateActionOracle}.sol
├── periphery/
│   ├── Router.sol             deposit-and-sell-YT, buy-PT/YT helpers
│   ├── OracleReader.sol       Chainlink wrapper (staleness, weekend, sequencer)
│   └── interfaces/{AggregatorV3Interface, ISwapPool}.sol
├── governance/
│   └── Guardian.sol           pause, early-settle, classifier dispute (multisig-owned)
└── mocks/                     test doubles (Stock Token, feeds, CPMM, classifier)
```

Key vault entry points: `deposit`, `redeemBeforeMaturity`, `redeemPT`, `redeemYT`,
`settle`, `emergencySettle`, `previewRedeemPT/YT`, `currentDividendGrowth`.

---

## 8. Launch series

| Ticker | Name           | Rationale                         |
|--------|----------------|-----------------------------------|
| KO     | Coca-Cola      | Flagship, reliable quarterly div  |
| SPY    | S&P 500 ETF    | Depth / legibility                |
| SCHD   | Dividend ETF   | High-yield dividend exposure      |
| QQQ    | Nasdaq 100 ETF | Max recognition, low yield        |

Maturity: **31 DEC 2026** (a ~6-month series aligned after known ex-div dates).
Verify token availability on-chain at build time.

---

## 9. What v1 does NOT build

No custom time-decay AMM (v1 uses mint/redeem + a seeded constant-product pool /
Uniswap), no continuous YT claiming, no protocol stablecoin/lending/liquidations,
no governance token (points tracked off-chain). See the README risks register and
the brief's Phase-2 list.
