> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spiralstake.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Stock + yield vaults

> Hold a tokenized stock 1x and farm a yield loop with the borrowed share — on Robinhood Chain.

An **equity vault** is two legs the user holds directly, entered and exited as one atomic batch:

1. **Stock leg** — the USDG deposit is swapped to a Robinhood tokenized stock (SPY, NVDA, TSLA, SPCX, AAPL) and posted as the user's own collateral on a partner Morpho market (`curator`: Longbow or NetNet Credit). A share of its value — the stock-leg LTV, 50% by default — is borrowed back as USDG.
2. **Yield leg** — that USDG is flash-looped into a Spiral yield strategy (syrupUSDG/USDG) at the yield market's max-safe LTV.

The user stays **1x long the stock** and earns the loop's leveraged yield on the borrowed share. A vault's `leverageApyPct` is therefore the **net dollar APY on the deposit** at the default stock LTV, not a leverage choice.

<Steps>
  <Step title="Discover">
    ```ts theme={null}
    const { strategies } = await call("list_strategies", { category: "stocks", chainId: 4663 });
    ```

    Each vault carries `curator`, `collateral.description`, `oracle.type: "market"`, its stock's `exitLiquidity`, and `spiralHints.profile.leverageApyMeaning`. Two NVDA vaults exist — one per curator.
  </Step>

  <Step title="Simulate at the user's size">
    ```ts theme={null}
    const sim = await call("simulate_equity_deposit", {
      strategyId: vault.id, amount: "10000", stockLtvPct: "50", chainId: 4663,
    });
    ```

    Read `stock.liquidationPriceUsd` and `priceDropToLiquidationPct` (the stock's fall to liquidation), `netApyPct`, and the fees. A higher `stockLtvPct` raises the net APY and shrinks the headroom; above the cap (`stock.maxLtvPct`) the call is refused.
  </Step>

  <Step title="Build the batch">
    ```ts theme={null}
    const bundle = await call("build_equity_deposit_tx", {
      strategyId: vault.id, amount: "10000", stockLtvPct: "50", userAddress: "0x…", chainId: 4663,
    });
    ```
  </Step>

  <Step title="Sign as one atomic batch">
    Submit `bundle.calls` via EIP-5792 `wallet_sendCalls` (or a Safe), or hand the user `bundle.meta.signingUrl`. A wallet that cannot batch sends the calls in order and always sends the final revoke.
  </Step>

  <Step title="Monitor">
    ```ts theme={null}
    const { equityPositions } = await call("get_positions", { userAddress: "0x…", chainId: 4663 });
    ```

    Watch `stock.ltvHeadroomPct` / `priceDropToLiquidationPct` on the stock leg and `yieldLoops[].ltvPct` on the yield leg.
  </Step>

  <Step title="Exit">
    ```ts theme={null}
    const exit = await call("build_equity_exit_tx", { strategyId: vault.id, userAddress: "0x…", chainId: 4663 });
    ```

    One batch closes the yield loop(s) and unwinds the stock leg; `meta.estimatedUsdgOut` is what comes back.
  </Step>
</Steps>

## Risks to weigh

* **Stock price.** The stock leg is priced by a Chainlink market feed; it liquidates if the stock falls to `ltvPct.liquidation` (a 20% drop at the default 50% LTV on a 62.5% market).
* **Yield-leg rates.** The loop runs near its max LTV; if its borrow rate rises above the collateral yield, `netApyPct` falls and can go negative. `simulate_equity_deposit` and `equityPositions.currentNetApyPct` show the live figure.
* **Exit liquidity.** The vault exits by selling the stock on the same aggregator it bought it on — read the stock's `exitLiquidity` at the position's size.
* **Liquidity to borrow.** The stock market must have `liquidityUsd` to lend the borrow, and the yield market must fund the flash loop directly; both are checked before quoting.

<Warning>
  Never close a vault's yield loop with `build_manage_tx` — it is refused, because doing so would leave the stock leg standing with its debt. Always use `build_equity_exit_tx`.
</Warning>
