Section 12 of 18
Single-Strategy Vault MVP
Final Build
Submit your complete protocol and run the full test suite. Earn the "yearn-v2-builder" badge on completion.
Single-Strategy Vault MVP
You have built sections 2 through 11. Vault chain: sections 2-6 and 9-11. Strategy chain: sections 7 (interfaces) and 8 (BaseStrategy). This is a checkpoint: the test for this section verifies that everything integrates correctly. No new code is added here.
What Should Work Now
If you connect a single concrete strategy to the vault you have built, this end-to-end flow runs:
- Deploy and initialize. Constructor (or
initVaultfor isolated tests) sets token, name, symbol, and roles.activationis set;lastReportis set. - User deposits.
deposit(amount, recipient)mints share tokens to the recipient using the virtual-offset math from section 5.totalIdleincreases byamount. The first depositor pays the cost of the virtual offset (negligibly). - Governance adds a strategy.
addStrategy(strategyAddr, debtRatio, min, max, perfFee)registers it and appends to the withdrawal queue. - Strategy harvests for the first time. It reads
creditAvailable(self)(gets the fullmin(strategy_DebtLimit, vault_DebtLimit, totalIdle, maxDebtPerHarvest)), pulls that credit by callingreport(0, 0, 0)with no gain or loss yet. Vault transfers credit to strategy; strategy.totalDebt increases; vault.totalIdle decreases by the same amount. - Strategy earns yield off-chain. Time passes. Strategy's underlying balance grows beyond its
totalDebt. - Strategy reports gain. It calls
report(gain, 0, 0). The vault validates the gain against the strategy's actual balance, charges 0 fees (section 16 not yet built), updatesstrategy.totalGainandstrategy.totalDebt += creditfor any new credit available, and locks the gain inlockedProfit(naive: full gain, since section 13's decay isn't built yet). - User withdraws. If
totalIdlecovers the requested value, the vault transfers from idle. (Section 14 adds the queue-iteration path for the case where it doesn't.)
What's Missing
You will add the rest in Part 3:
- Locked profit degradation (section 13): the just-in-time defense. Without it, a depositor could front-run a harvest and claim the freshly-reported gain. Right now
_updateLockedProfitis a naive stub that locks the full gain; once you build the time-decay version, the lock unlocks linearly over ~6 hours. - Multi-strategy withdraw (section 14): the user's withdraw call when
totalIdleis insufficient. Walks thewithdrawalQueue, pulls from each strategy, accounts for losses. - Strategy harvest cycle (section 15): the actual
harvest()andtend()functions onBaseStrategy's subclass that orchestrate_prepareReturn → vault.report → _adjustPosition. - Fees (section 16): management fee accruing on
totalDebt, performance fees on gain, fee-as-share-mint mechanism. Right now_assessFeesis a stub returning 0. - Emergency shutdown and the deployable constructor (section 17): the
Vaultcontract that ships to mainnet, plus the emergency switch that drains every strategy on the next harvest.
How the Test Verifies This
tests/12-vault-mvp-checkpoint.json checks structural integrity:
- The contract chain is intact:
VaultStorage → VaultShareToken → VaultShareMath → VaultDeposit → VaultTotalAssets → VaultAddStrategy → VaultCreditDebt → VaultReport. - The key public functions exist with the right signatures:
deposit,totalAssets,addStrategy,creditAvailable,debtOutstanding,report. - The storage variables that span sections are present:
totalIdle,totalDebt,strategies,withdrawalQueue,lockedProfit. - The first-depositor defense constants and override are in place.
The test does NOT execute Solidity (the runner is a regex matcher). If you want to verify behavior, deploy the chain to a local Anvil and run a hand-written Foundry test through the seven-step flow above.
Take a Break
Part 3 raises the difficulty. Sections 13 and 14 add the most subtle math in the module (time-decay locking, multi-strategy queue iteration with loss accounting). The MVP you have right now is the design Yearn V1 was, a single-strategy vault with no JIT defense. Part 3 turns it into Yearn V2.