Documentation
Everything the optimizer does, why it does it that way, and how to verify it on-chain.
System Overview
YieldForge is an ERC-4626 vault on Robinhood Chain (chain id 4663). Deposit any of AAPL, NVDA, GOOGL, USDGand the vault mints shares 1:1 against your USDG-denominated position. Every asset lands in the same pool of capital — the optimizer doesn't care which token you deposited, only how much it's worth.
From there, the optimizer scores every connected venue and routes deployable capital to whichever one clears the highest risk-adjusted score. You hold a vault share; routing is the vault's job.
Why Rules, Not a Model
The optimizer is a deterministic formula, not a model. There's no training data, no inference, and no confidence interval — just five inputs multiplied together in a fixed order, on-chain, every time.
Same inputs in, same route out. If you disagree with a routing decision you can recompute it yourself from the inputs hash published in every DecisionAttested event — there's no opaque scoring step to trust blindly.
Optimizer Cycle
The optimizer runs the same four steps every cycle, roughly every 6 hours.
- 1
Trigger
A fixed schedule wakes the optimizer. No manual kickoff, no admin button.
- 2
Score
Every connected venue is scored against the same five inputs using the formula below.
- 3
Attest
The winning decision — venue, APYs, and an inputs hash — is written on-chain before any funds move.
- 4
Route
Capital moves to the winning venue. If the last decision is stale, the vault refuses to route on it.
Vault & Adapters
Every venue the vault can route to is wrapped in an IVenueAdapter contract, giving the vault a uniform interface regardless of what the underlying protocol looks like.
deposit(uint256 amount)Push idle vault capital into the venue.withdraw(uint256 amount)Pull capital back out of the venue on demand.totalDeployed()Capital currently held by this venue, in vault-asset terms.maxDeposit()Remaining capacity before the venue is considered at capacity.venueId()The registry id this adapter answers to.rawApy()The venue's current unadjusted APY, 1e18-scaled.receiveAsset()The underlying asset the venue accepts (USDG).New venues are added by the vault owner via addVenue(adapter, cap), which emits VenueAdded and registers it in the venue set the optimizer scores on the next cycle. Removing a venue is symmetric via VenueRemoved.
Live Venues
Two venues are connected today. Both are USDG markets; both are re-scored every cycle, so nothing here is a permanent allocation.
| Venue | Raw APY | Risk | Liquidity | Depth | Risk-adj APY |
|---|---|---|---|---|---|
| Steakhouse | 3.44% | 0.70 | 1.00 | 1.00 | 2.41% |
| Steakhouse (Live) | 0.30% | 0.70 | 1.00 | 1.00 | 0.21% |
| Morpho | 3.40% | 0.70 | 0.98 | 1.00 | 2.33% |
| Longbow USDG Core | 0.01% | 0.65 | 1.00 | 1.00 | 0.01% |
Full adapter addresses and a longer breakdown live on the Venues page.
Scoring Formula
Every venue's risk-adjusted APY comes from one formula, computed 1e18-scaled on-chain:
Five inputs feed the formula:
- APY
- TVL
- Liquidity depth
- Protocol risk
- Historical volatility
See the full worked example and live last-decision readout.
Technical Specs
0xaf3d76f1834a1d425780943c99ea8a608f8a93f918 dec0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec18 dec0x2e0847e8910a9732eb3fb1bb4b70a580adad4fe318 dec0x5fc5360D0400a0Fd4f2af552ADD042D716F1d1686 decCore ERC-4626 + routing calls:
deposit(assets, receiver)Deposit USDG, mint vault shares to receiver.depositAsset(asset, amount)Deposit AAPL/NVDA/GOOGL directly; priced and converted internally.withdraw(assets, receiver, owner)Burn shares, withdraw USDG.redeem(shares, receiver, owner)Burn a specific share amount, withdraw the underlying value.positions(user)A user's shares, USDG value, and per-asset breakdown.lastDecision()The most recent optimizer decision: venue, APYs, inputs hash, timestamp.FAQ
Is this an AI-managed vault?
No. The optimizer is a fixed scoring formula, not a model. There's nothing to fine-tune and no inference step — see “Why Rules, Not a Model” above.
Who can trigger a rebalance?
Nobody manually. A keeper wakes the optimizer on a fixed schedule (every 6 hours) and it scores every connected venue the same way, every time.
What happens if a decision goes stale?
The vault rejects routing on any decision older than 1h. Capital sits idle rather than routing on stale data.
Can the vault hold my keys?
No. YieldForge is non-custodial — every deposit, withdrawal, and approval is signed from your wallet. The app never holds keys and never auto-submits transactions.
How are new venues added?
The vault owner registers a new IVenueAdapter with addVenue(adapter, cap), emitting a VenueAdded event. The optimizer picks it up on the next scoring cycle — no migration required.
What if every venue scores below the idle threshold?
Capital stays in the idle reserve. The optimizer never forces an allocation — a venue has to earn it.