HoodStash protocol design
Version 0.6.
HoodStash is a system of covered-call vaults for tokenized stocks. Depositors supply stock tokens. A public batch auction sells option claims. Winners pay premium in a dollar token. Claim holders can exercise against covered stock after an eligible settlement.
0. Design principles
- The vault uses asynchronous deposit and withdrawal requests.
- The weekly option lifecycle is the only new accounting layer.
- The vault never sends stock for an exercise without receiving the strike payment in the same transaction.
- The protocol records a rule for every known edge case.
- Current financial state comes from the chain.
- Unsafe price data delays an action. It never produces a fallback price.
1. System overview
Contracts
| Component | Responsibility |
|---|---|
| Covered-call vault | Holds assets, issues shares, maintains queues and accounting buckets, and runs weekly phases. |
| Option manager | Stores each option position, enforces strike and price rules, and records settlement. |
| Option auction | Escrows bids, clears one public price, creates claim allocations, handles refunds, and routes exercise. |
| Claim token | Represents transferable exercise rights for each option series. |
| Basket token | Represents fixed weights of supported stock tokens. |
| Basket router | Acquires basket constituents and mints basket tokens in one transaction. |
| Fee splitter | Routes the premium fee. |
| Insurance pool | Holds the dollar-token first-loss reserve for defined settlement shortfalls. |
Roles
| Role | Power |
|---|---|
| Keeper | Calls permissionless transitions on time. It has no exclusive transition right. |
| Guardian | Pauses permitted operations. It cannot move user funds. |
| Governance | Changes approved parameters through a 48-hour timelock. Contract limits still apply. |
| Bidder | Escrows a bid in the public auction. |
| Claim holder | Owns and can exercise a transferable claim. |
No administrator can withdraw user funds.
Off-chain components
- The frontend reads current financial state from contracts.
- The keeper sends idempotent transition transactions.
- The indexer records events for history and analytics.
- The shared package publishes generated contract interfaces, chain definitions, addresses, and domain types.
The database never decides whether a transaction is valid.
2. Weekly lifecycle
Every transition is a permissionless contract call.
Deposit window
- A user can request a deposit while the vault accepts requests.
- The vault places the stock tokens in the pending bucket.
- The request becomes active at the next eligible weekly boundary.
- A pending deposit does not earn the current premium and does not support the current option.
- The owner can cancel a pending deposit before activation.
Auction
- The auction opens with a coverage snapshot.
- The contract computes a deterministic strike from the opening price and volatility report.
- Anyone can bid dollar tokens.
- Bids close at the configured time.
- The auction clears at one price.
- The premium moves to the vault.
- Winners can mint their allocated claims.
- Eligible pending deposits activate for the new round.
Active
- The option is outstanding.
- The vault holds enough stock to cover every sold claim.
- A user can queue a withdrawal.
- An active withdrawal cannot remove stock that supports a claim.
Settlement
- A caller submits the first eligible price round at or after expiry.
- The contract validates the round and its predecessor.
- The contract writes the settlement price once.
- A below-strike series becomes non-exercisable.
- An at-or-above-strike series opens its exercise window.
Exercise window
- Only a claim holder can exercise.
- The holder chooses an amount.
- The contract burns that claim amount.
- The vault pulls exactly
strike × amountin the dollar token. - The vault sends the matching stock amount in the same transaction.
- Total exercise cannot exceed the sold amount.
Cooldown
- The vault credits premium after the fee.
- The vault processes eligible withdrawals.
- Users claim their processed withdrawals.
- Unused claims lapse after the exercise window.
- The next auction can begin when the phase rules allow it.
3. Vault accounting
Vault standard
The vault uses ERC-7540-style request semantics with an ERC-20 share token.
A deposit or withdrawal request is not an instant ERC-4626 conversion. The request receives the price of its target weekly boundary.
Accounting buckets
Every token balance belongs to one bucket.
| Bucket | Asset | Meaning |
|---|---|---|
activeUnderlying | Stock token | Supports active shares and option coverage. |
pendingUnderlying | Stock token | Belongs to pending deposit requests. |
premiumUsdG | Dollar token | Collected premium that has not completed distribution. |
exerciseProceedsUsdG | Dollar token | Strike payments from exercised claims. |
feesAccruedUsdG | Dollar token | Accrued protocol fee. |
withdrawalClaimsUnderlying | Stock token | Stock owed to processed withdrawals. |
withdrawalClaimsUsdG | Dollar token | Dollar token owed to processed withdrawals. |
unclaimedDepositShares | Vault shares | Shares minted for deposits that owners have not claimed. |
Bucket sums must match the corresponding token balances.
Share pricing
The vault computes net asset value from:
- active stock value;
- dollar-token balances that belong to shareholders;
- fixed option liabilities after settlement; and
- outstanding withdrawal claims.
Pending deposits do not affect the current share price.
The share-mint calculation keeps the virtual-share offset to reduce first-deposit inflation attacks.
Deposit requests
requestDepositrejects an unbound vault.- A request records its owner, stock amount, and target weekly round.
cancelDepositreturns stock before activation.- Activation mints claimable vault shares.
- A user claims the shares after activation.
Withdrawal requests
- A request escrows vault shares immediately.
- The owner can cancel before the target round locks.
- The vault processes requests in bounded batches.
- Each processed request records stock and dollar-token claims.
- The owner pulls the claim.
Fee
The fee is 12% of collected option premium.
- Ten percentage points follow the configured recipient split.
- Two percentage points fund the first-loss reserve until its target.
- The fee never comes from principal.
- Zero premium produces zero fee.
4. Option position and strike
The option manager stores one position for the current series:
- series identifier;
- strike;
- offered amount;
- sold amount;
- exercised amount;
- expiry;
- premium;
- opening price round;
- opening price; and
- settlement price.
There is no single buyer. Transferable claim holders own exercise rights.
Strike bounds
The contract computes:
strike = openingPrice × (1 + strikeDistanceBps / 10,000)
The keeper reports weekly volatility and a proposed distance. The contract clamps that distance with:
- a per-vault floor;
- a per-vault ceiling; and
- a maximum change from the prior weekly distance.
Governance changes the policy only through the timelock. No role chooses an unrestricted strike.
When the keeper has insufficient valid data, it submits the no-report form. The contract uses the prior distance. The keeper never invents volatility.
5. Public option auction
Series
One auction serves one vault and weekly round.
The series records:
- vault and round;
- stock and dollar-token addresses;
- offered coverage;
- strike;
- bid close and expiry times;
- exercise duration;
- minimum total premium;
- maximum bid count;
- claim identifier;
- opening price round; and
- opening price.
Opening requires a usable price, a clear token price-pause flag, and a safe sequencer state.
Bids
A bid records:
- bidder;
- refund receiver;
- requested claim amount;
- maximum premium per unit;
- escrowed dollar tokens;
- creation time;
- replacement count;
- active state; and
- allocation-claim state.
The bidder escrows amount × maximum premium.
A minimum notional prevents dust bids. A maximum bid count bounds close-time work. A replacement keeps the slot. A cancellation frees it before close. A higher bid can evict the lowest bid when the book is full.
Clearing
- Order active bids by maximum premium, highest first.
- Break equal-price ties by ascending bid identifier.
- Fill until coverage is used or demand ends.
- Set the clearing premium to the lowest accepted premium.
- Fill equal-price margin bids proportionally.
- Round fills down.
- Allocate any rounding remainder in bid order without exceeding a request.
Every winner pays the clearing premium.
The sold amount is min(demand, coverage). Unsold stock cannot be exercised.
If clearing premium times sold amount is below the minimum total premium, the auction skips and all bids become refundable.
The escrow identity is:
escrow = premium sent to the vault + refund liabilities
Refunds are pull-based.
Claim tickets
- Each winner mints its own allocation.
- One claim identifier represents one series.
- Claims are divisible and transferable.
- The current holder can exercise.
- Supply cannot exceed filled claims minus exercised or terminally burned claims.
- Metadata can show vault, strike, expiry, and state.
Pause behavior
- A pre-clear pause cancels the auction and makes every bid refundable.
- A post-clear pause cannot remove a claim or refund right.
- A pause during exercise extends the deadline by the paused duration.
- Emergency exit can void unsettled claims under its rules.
- Settled in-the-money claims remain fixed liabilities.
Accepted auction risks
- Thin demand can clear at the minimum.
- Public bids reveal price and size.
- High bidders can pay less than their maximum because every winner pays one clearing price.
- A last-block bid follows the same ordering rules as every other bid.
6. Basket assets
A basket token represents fixed weights of supported stock tokens.
- Minting requires proportional constituent deposits.
- Redemption returns proportional constituents.
- The MVP does not rebalance.
- Net asset value sums each constituent balance times its usable price.
- Every feed uses its own runtime decimal value and staleness rule.
The basket router can acquire all constituents and mint a basket in one transaction. A failed leg reverts the complete transaction. The router holds no balance between transactions.
A vault can accept an approved stock token or basket token when it has a computable dollar price.
7. Price safety
Settlement round
settle(roundId) accepts a round only when:
updatedAtis at or after expiry;- the round arrived no later than one configured heartbeat after expiry;
- the preceding round is before expiry;
- the answer is positive and complete;
- the current price status is usable;
- the token price-pause flag is false; and
- the sequencer is up and past its recovery period.
The contract writes the settlement price once.
If no eligible round exists, settlement waits.
Other price reads
Net asset value, strike, and deposit pricing reject a price older than the configured heartbeat.
All price-dependent auction transitions use the same safety gates.
Corporate actions
The stock token can report that its price is paused.
When the flag is true:
- do not open a price-dependent auction;
- do not settle;
- reject other price-dependent reads; and
- wait until the flag clears and the price is fresh.
The price feed already includes the stock token multiplier. Settlement math never applies the multiplier a second time.
Sequencer status
When a sequencer feed is configured:
- a down result makes the price unusable; and
- a recent recovery stays unusable for the complete grace period.
A zero sequencer-feed address means that no sequencer check is configured. All other price rules still apply.
Units and rounding
- Read every token and feed decimal value at runtime.
- Normalize price math to 18 decimals.
- Use a denominator of 10,000 for basis-point policy values.
- Round conversions in the vault's favor.
- Round deposit shares down.
- Round withdrawal assets down.
- Round fees up.
8. Fee splitter and first-loss reserve
The fee splitter receives the 12% premium fee.
- Ten points follow the configured recipient split.
- Two points go to the first-loss reserve until its target.
- Recipients pull their allocations.
- The contract uses no unbounded payout loop.
The first-loss reserve:
- holds only the dollar token;
- cannot pay more than its balance;
- pays only a verified settlement shortfall;
- caps one event at 30% of the pool;
- requires a timelocked governance action; and
- does not guarantee user balances.
9. Administration, pause, and upgrades
The MVP contracts are immutable. They do not use an upgrade proxy.
The recovery sequence for a defect is:
- pause;
- let users use the permitted exit path;
- deploy a new version; and
- let users opt in to migration.
Emergency exit
After the required pause or feed-halt delay, a holder can redeem vault shares for its proportional stock and dollar-token buckets.
The path:
- reads no price;
- needs no keeper;
- cannot ignore settled claim liabilities; and
- can forfeit undistributed premium under the contract rule.
Deposit cap
Each vault can enforce a stock-token deposit cap.
The cap includes active stock, pending stock, and the new request. Governance changes it through the timelock.
Privileged actions
| Action | Authority | Constraint |
|---|---|---|
| Change strike policy rails | Governance | 48-hour timelock and contract bounds. |
| Change heartbeats, allowlists, fee routing, or deposit cap | Governance | 48-hour timelock. |
| Pause | Guardian | Cannot move funds or force stale settlement. |
| Pay a verified shortfall | Governance | 48-hour timelock and 30% pool limit. |
| Withdraw user funds | Nobody | No such administrative function exists. |
10. User and data flows
Depositor
- Connect a wallet.
- Select a vault.
- Approve the exact stock amount.
- Request a deposit.
- Wait for activation.
- Hold vault shares through the weekly option.
- Request a withdrawal.
- Wait for processing.
- Claim the resulting assets.
Bidder
- Read the series and auction book.
- Escrow a maximum-price bid.
- Read the final fill and refund.
- Mint a winning allocation.
- Hold or transfer the claim.
- Exercise during an eligible window or let the claim lapse.
- Pull any refund.
Data rule
- Contract reads decide current financial state.
- Contract simulation checks a transaction.
- Events and the indexer provide history.
- The indexer cannot make a transaction valid.
11. Edge-case rules
| Edge | Rule |
|---|---|
| Late deposit after premium is known | The deposit targets the next weekly round. |
| Mid-round withdrawal | Shares escrow and process after the option obligation permits it. |
| No auction demand | The weekly option can skip. Stock remains in the vault. |
| Stale price at expiry | Settlement waits. |
| Token price pause | Price-dependent actions wait for a clear flag and fresh price. |
| Market holiday | Expiry uses the configured last trading day. |
| Wrong decimals | Read decimals at runtime and normalize. |
| Dust bids | Enforce minimum notional and bounded bid count. |
| Demand below coverage | Sell only demand. Unsold stock has no claim. |
| Premium below minimum | Skip and make every bid refundable. |
| Pause before clearing | Cancel and make every bid refundable. |
| Pause after clearing | Preserve claims and refunds. Extend exercise time. |
| Settled claim during emergency | Treat it as a fixed liability. |
| Claim not exercised | Lapse it after the deadline. Stock remains in the vault. |
| Queue gas pressure | Process bounded batches and let users pull claims. |
| Reentrancy attempt | Use checks, state updates, external calls, and reentrancy guards. |
| First-deposit inflation | Keep the virtual-share offset. |
12. Initial parameters
| Parameter | Initial value |
|---|---|
| Weekly expiry | Friday at 16:00 ET, or the configured last trading day |
| Coverage | Up to 100% of active stock |
| Strike band | 5% to 30% above opening price |
| Minimum premium | 0.1% of sold notional |
| Premium fee | 12% of premium |
| Exercise window | 48 hours after settlement |
| Reserve event cap | 30% of reserve balance |
| Launch vault | TSLA single-stock vault |
Read current contract values before using a configurable parameter.