# Token as collateral (rwa_collateral)

Desk: Tokenized assets. Page: https://hedgefund.md/models/rwa_collateral

**What it asks.** How far is a loan against a token from liquidation on the oracle's clock and on the redemption clock, and what does a liquidation through the pool leave behind?

Takes a loan against a token: health factor, fall to liquidation, that fall in stdevs over the oracle lag and the redemption time, the driftless chance of touching the line, a whole-position liquidation through a constant-product pool with slippage and bad debt, carry, the highest LTV for a buffer, and repeated borrowing. Every number comes from the caller. Not a price, a rating or advice.

Results are hypothetical: arithmetic on the numbers sent, a made-up template or a stated default. Nobody achieved them, and they aren't a forecast, a recommendation, an offer or a record of real trading. Don't show any output to investors or clients, or use it to market an investment. Terms: https://hedgefund.md/terms

## Inputs

| Input | Type | Range | Required | What it is |
| --- | --- | --- | --- | --- |
| `collateral_value` | number | over 0 to 10000000000000 | yes | Collateral at the oracle's price. |
| `debt` | number | over 0 to 10000000000000 | yes | Debt owed. Above zero: with no debt there is no line. |
| `liquidation_threshold_pct` | number | over 0 to 100 | yes | Debt can reach this share of collateral before liquidation. 80 means 80%. |
| `liquidation_penalty_pct` | number | 0 to 50 | yes | Share of liquidation proceeds taken first as the penalty. 5 means 5%. |
| `asset_vol_pct` | number | 0 to 500 | yes | Annual volatility of the token's value. 15 means 15%. |
| `oracle_lag_hours` | number | 0 to 8760 | yes | Hours the oracle's price can lag. |
| `redemption_days` | number | 0 to 3650 | yes | Days to turn the token into cash by redemption. |
| `pool_cash_depth` | number | over 0 to 10000000000000 | yes | Cash in the constant-product pool. |
| `pool_token_depth` | number | over 0 to 10000000000000 | yes | Tokens in the constant-product pool. |
| `borrow_rate_pct` | number | 0 to 100 | yes | Interest on the debt. 7 means 7%. |
| `asset_yield_pct` | number | 0 to 100 | yes | Yield on the collateral. 9 means 9%. |
| `buffer_sigmas` | number | 0 to 10 | no | Optional. Stdevs of cushion for the highest LTV. Default 3. |
| `oracle_price` | number | over 0 to 1000000000 | no | Optional. Oracle's price per token. Default: the pool's mid, y / x. |
| `loop_ltv_pct` | number | 0 to 99 | no | Optional. LTV for the repeated borrowing table. Default: this loan's LTV. |

## Template

Made-up numbers that run as they stand, so you can see the shape of a result. They aren't market levels, typical values or estimates, and the names in them don't exist. Replace every number before you read anything into a run.

```json
{
  "collateral_value": 10000000,
  "debt": 7000000,
  "liquidation_threshold_pct": 80,
  "liquidation_penalty_pct": 5,
  "asset_vol_pct": 15,
  "oracle_lag_hours": 24,
  "redemption_days": 90,
  "pool_cash_depth": 30000000,
  "pool_token_depth": 300000,
  "borrow_rate_pct": 7,
  "asset_yield_pct": 9,
  "buffer_sigmas": 3
}
```

## What the template gives

On these numbers, the health factor is 1.143, the line is 17 stdevs away over the oracle lag and 1.79 over the redemption time, a liquidation at the line through the pool leaves 663,310 of bad debt, and the highest LTV for 3 stdevs is 63.98% against 70% now.

- Health factor: 1.1429 (watch)
- Fall to the line: 12.5%
- Stdevs to the line, oracle lag: 17.01
- Stdevs to the line, redemption: 1.7927 (watch)
- Slippage selling at the line: 23.77% (breach)
- Bad debt at the line: 663,310 (breach)
- Hypothetical carry a year: 410,000
- Highest LTV for the buffer: 63.98% (breach)

Where it flips, with the other inputs held:

- `asset_vol_pct` at 8.9637: At this vol the loan sits exactly 3 stdevs from the line over the redemption time. Above it the line is closer than that.
- `redemption_days` at 32.1392: At this redemption time the loan sits exactly 3 stdevs from the line. Longer than this, the line is closer than that.
- `pool_cash_depth` at 49888765.16: With this much cash in the pool, at the same price, a liquidation at the line just clears the debt after slippage and penalty. With less it leaves bad debt.

## Formula

Health = C * threshold / D. Fall to the line = 1 - 1 / health. z = ln(health) / (vol * sqrt(t)). Touch chance = 2 * Phi(-z). Pool at a price ratio p: y' = y sqrt(p), x' = x / sqrt(p), proceeds = y' n / (x' + n). Bad debt = max(0, D - proceeds * (1 - penalty)). Carry = C * yield - D * borrow. Highest LTV = threshold * exp(-sigmas * vol * sqrt(t)). Loops: exposure = (1 - L^(n+1)) / (1 - L), limit 1 / (1 - L).

## Assumptions

- Health factor = collateral * threshold / debt. The line is where it equals 1, at a collateral value of debt / threshold.
- Returns are lognormal with no drift. The distance to the line is ln(health factor), not the simple percent fall. z = distance / (vol * sqrt(t)), with t = hours / 8760 or days / 365, a 365-day calendar.
- The chance of touching the line within t is 2 * Phi(-z), the driftless reflection formula. It is an approximation: no drift, constant vol, continuous watching, no jumps. The chance of being under the line at the end of t alone is half of it.
- The pool is constant-product with no fee. Without oracle_price, the tokens to sell are collateral / pool mid, so at value V the proceeds are V * y / (V + y), and token depth cancels out.
- A liquidation at the line comes after the price fall, so arbitrage has already moved the pool: its product holds, cash depth falls to y * sqrt(p) and token depth rises to x / sqrt(p), where p is the price against today. The pool's gap to the oracle stays as it is.
- Liquidation sells the whole position. The penalty comes off the proceeds first. Bad debt = max(0, debt - proceeds * (1 - penalty)). Anything over the debt goes back to the borrower.
- The row for an oracle lag takes a further fall of buffer_sigmas stdevs over the lag, past the line, before the sale. The redemption row has no slippage but takes that fall over the redemption time.
- Carry = collateral * yield - debt * borrow, a year, before costs. On equity it is over collateral less debt.
- Highest LTV = threshold * exp(-buffer_sigmas * vol * sqrt(redemption time)). At that LTV the line is exactly buffer_sigmas stdevs away.
- The loop table starts from the sent collateral with no debt. After n loops at LTV L, exposure is (1 - L^(n+1)) / (1 - L) per 1 of capital, debt is that less 1, and everything stays at the same price.

## Not modeled

- Other borrowers liquidating through the same pool at the same time, which is the usual case in a fall.
- Liquidity providers leaving the pool as the price falls, beyond the arbitrage move above.
- Partial liquidation and the capital a liquidator needs. A liquidator may not exist at this size.
- Jumps, and hours when the asset under the token can't trade while the token still can.
- Interest on the debt and yield on the collateral during the window. The line is held still.
- Oracle errors or manipulation, beyond the lag sent.
- Gates, queues and minimums on the redemption route.
- Whether this holder may acquire, hold, mint, redeem, pledge, sell or transfer this token, or use any pool. Those are legal questions for counsel.
- Taxes and transaction costs.

## Call it

Every result has the same fields: summary, readings, tables, charts, flags, flips, formula, assumptions, not_modeled, hypothetical and inputs_hash. Read flags, flips and not_modeled with the summary, and pass them along together.

### HTTP

No key. The tools keep nothing you send. Send positions by POST, because a URL can land in a server log.

```bash
curl -s https://hedgefund.md/api/v1/rwa_collateral \
  -H 'content-type: application/json' \
  -d '{"collateral_value":10000000,"debt":7000000,"liquidation_threshold_pct":80,"liquidation_penalty_pct":5,"asset_vol_pct":15,"oracle_lag_hours":24,"redemption_days":90,"pool_cash_depth":30000000,"pool_token_depth":300000,"borrow_rate_pct":7,"asset_yield_pct":9,"buffer_sigmas":3}' \
  | jq '{summary, flags, flips, not_modeled, inputs_hash}'
```

### MCP

The tool is `rwa_collateral` on the server at https://hedgefund.md/mcp.

```bash
curl -s https://hedgefund.md/mcp \
  -H 'content-type: application/json' -H 'accept: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"rwa_collateral","arguments":{"collateral_value":10000000,"debt":7000000,"liquidation_threshold_pct":80,"liquidation_penalty_pct":5,"asset_vol_pct":15,"oracle_lag_hours":24,"redemption_days":90,"pool_cash_depth":30000000,"pool_token_depth":300000,"borrow_rate_pct":7,"asset_yield_pct":9,"buffer_sigmas":3}}}' \
  | jq '.result.structuredContent | {summary, flags, flips, not_modeled, inputs_hash}'
```

### The library

The same code on your own machine, with no dependencies, and nothing is sent anywhere.

```bash
curl -fsSL https://hedgefund.md/hedgefund.mjs -o hedgefund.mjs   # read it before you run it
node hedgefund.mjs template rwa_collateral > mine.json           # replace every number in it
node hedgefund.mjs run rwa_collateral mine.json | jq '{summary, flags, flips, not_modeled, inputs_hash}'
```

In a script:

```js
import { run, template } from "./hedgefund.mjs";

const inputs = template("rwa_collateral"); // replace every number in it
const { summary, flags, flips, not_modeled } = run("rwa_collateral", inputs);
```
