Core concepts

The vocabulary you need to read the rest of the docs.

Basket

A basket is a smart-contract vault (the Basket contract) that holds 2–20 tokenized stocks and issues its own ERC-20 shares. Owning shares means owning a proportional claim on everything the vault holds. A basket is created by a creator, who sets the constituents, weights, and fees, and earns 90% of the fees the basket charges.

Shares

Shares are standard 18-decimal ERC-20 tokens minted by the basket. Your slice of the vault is yourShares / totalSupply. Shares are minted when you buy and burned when you redeem.

  • DEAD_SHARES (1e15) — at creation, a tiny fixed amount of shares is minted to a dead address and locked forever. This bootstraps a non-zero supply floor and protects against first-depositor / inflation attacks.

Constituents, weights, and trackedBalance

The constituents are the underlying tokens the basket holds. Each has a weight (in basis points, summing to 10,000) that the creator picks at deploy. The vault records how much of each token it holds in trackedBalance — its own internal accounting, which is what mint/redeem math uses (not the raw ERC-20 balance, so stray tokens sent directly to the vault can't distort accounting).

NAV and price-per-share

  • NAV (Net Asset Value) — the total USD value of everything the vault holds: Σ trackedBalance_i × price_i (normalized by each token's decimals). Prices come from Chainlink via OracleLib.
  • Price-per-shareNAV / totalSupply.

Important: NAV is used only for display, zap pricing, and fee accounting. It never gates deposits or withdrawals. If a price feed is stale, NAV is flagged stale and that constituent contributes 0 — but in-kind mint and redeem keep working, because they don't use prices at all.

Two ways to buy: in-kind vs. zap

In-kind Zap (one-click)
You provide The underlying tokens, in the vault's current ratio A single stablecoin (USDG)
Mechanism mintInKind — deposit tokens, get shares HoodZapRouter.zapIn — swaps USDG into every constituent, then mints
Pricing Oracle-free, pro-rata Depends on Uniswap v4 liquidity for each constituent
Always available? Yes Only if every constituent has a usable swap route

The reverse works too: redeem in-kind to get the underlying tokens back, or zap out to swap them all to USDG in one transaction.

Fees

Three fees, all capped and all split 90% creator / 10% protocol (PROTOCOL_CUT_BPS = 1000):

Fee Cap When charged
Entry 3% (300 bps) On every mint (in-kind or zap)
Exit 1% (100 bps) On every redeem
Management 3%/yr (300 bps) Streamed continuously via share dilution

The management fee accrues as newly-minted shares over time, split to creator/treasury; it slightly dilutes existing holders rather than charging them directly.

The wire-format contract (for API/app developers)

Every on-chain numeric amount is represented as a raw base-10 integer string — digits only, no decimal point — in the value's smallest unit. Divide by the token's scale to display:

  • Shares, NAV, USD values → 18 decimals (divide by 1e18).
  • USDG amounts → 6 decimals (divide by 1e6).
  • Basis-point fields, returns, chainId, timestamps → plain JSON numbers / ISO strings, not raw integers.

Never parse a raw-integer field as a JavaScript number — use a big-integer type. This is the single most common integration mistake.

USDG

USDG is the stablecoin used as the entry/exit asset for zaps. It has 6 decimals (so 1000000 = 1 USDG). It is itself a whitelisted token so its price feed is available for accounting.