Documentation Index
Fetch the complete documentation index at: https://docs.sherwood.sh/llms.txt
Use this file to discover all available pages before exploring further.
Redemption Lock During Active Strategy
When a strategy is live (proposal inExecuted state), the vault’s redemptionsLocked() returns true and withdraw / redeem / deposit / rescueERC20 all revert. Depositors can exit only after settlement, during the cooldown window.
WOOD/SHARES early-exit pool — aspirational, not live in V1. An earlier design proposed one-sided liquidity pools pairing WOOD with each vault’s share token, letting depositors swap out of locked vaults at a market-discovered discount. That design is not implemented in the shipped contracts; today the only exit path is waiting for settlement + cooldown. Early-exit liquidity is tracked for a future release.
WOOD Tokenomics (ve(3,3) stack)
The protocol ships a full ve(3,3)-style token economy (VotingEscrow, Voter, SyndicateGauge, Minter, VoteIncentive, RewardsDistributor, VaultRewardsDistributor) in addition to the governance + fee logic on this page. The surface is live in contracts/src/ but the public documentation is deliberately deferred — the surface is still stabilising around PR #229 (guardian rewards) and the early-exit design above.
Expanded ve(3,3) docs are forthcoming. See the in-repo reference
docs/tokenomics-wood.md for the current internal description of lock mechanics, gauge weights, bribe flows, rebase math, and Minter emissions. A dedicated tokenomics section will be added to these public docs once the guardian-reward epoch wiring (fundEpoch) and the Minter → registry integration land in V1.5.SyndicateGauge.claimLPRewardsalways reverts (_calculateLPRewardis stubbed). Gauge LP reward accrual is tracked but not claimable. Slices that already accrued under the legacy bootstrap schedule (epochs ≤ 12) can be recovered by the gauge owner viarescueStuckLPRewards(epoch, recipient)— emissions for new epochs no longer accrue to this slice (getLPRewardPercentagereturns 0).- Price and lock-ratio circuit breakers in
Minterare manual (multisig) today, not triggered automatically. - No WOOD/SHARES Uniswap V3 early-exit pool is deployed; the design in older drafts is not live.
- Guardian Block-side rewards (
fundEpoch+claimEpochRewardonGuardianRegistry) are wired, but Minter → registry auto-funding is V1.5; V1 relies on multisig-funded epochs (see Guardian Review).
Fee Structure
Three fees are distributed from strategy profits at settlement:| Fee | Recipient | Set by | Purpose |
|---|---|---|---|
| Protocol fee | protocolFeeRecipient | Factory owner (timelocked) | Protocol revenue |
| Performance fee | Agent (proposer) | Agent at proposal time | Incentivize good strategy proposals |
| Management fee | Vault owner | Factory (per-vault, configurable) | Incentivize vault operation and curation |
Protocol Fee
A protocol-level fee taken from gross profit before agent and management fees. This funds protocol development and operations.protocolFeeBps— percentage of gross profit taken as protocol fee (max 10% / 1000 bps)protocolFeeRecipient— address that receives the protocol fee- Both live on the governor and apply to every registered vault
- Both
setProtocolFeeBpsandsetProtocolFeeRecipientare timelocked through the same queue → delay → finalize pattern as every other governance parameter (6h–7d delay). Neither can be changed instantly. HistoricallysetProtocolFeeRecipientwas owner-instant; finding G-C5 in the pre-mainnet review closed the gap by routing the recipient change through_queueChange/_applyChange(address encoded asuint160). Vault operators and depositors now always have visibility into a pending recipient rotation.
Fee distribution order
Fees are calculated and distributed in a strict order — protocol fee first, then agent fee, then management fee:Management Fee
The management fee incentivizes vault operation — the owner curates agents, manages parameters, handles emergencies.managementFeeBps— configurable per-factory (max 10% / 1000 bps)- Applied to new vaults at creation time
- Owner only earns on profit — aligned with depositor outcomes
Try/catch fee transfers + unclaimed-fee escrow
Every fee transfer — protocol fee, agent / co-proposer performance fee, and vault owner management fee — is wrapped in try/catch aroundvault.transferPerformanceFee(asset, recipient, amount). If the transfer reverts (USDC blacklist, paused token, contract recipient with a failing receive, etc.) the governor:
- Credits the owed amount to an on-chain
_unclaimedFees[recipient][token]escrow mapping - Emits
FeeTransferFailed(recipient, token, amount, reason)so indexers can surface the stuck fee - Continues settlement without reverting
claimUnclaimedFees(vault, token) once the failure condition is cleared (they un-blacklist, rotate the recipient, unpause, etc.). Read via unclaimedFees(recipient, token).
This ensures:
- Depositor capital is never held hostage by a blacklisted fee recipient — settlement always completes
- Fees are not lost — they are escrowed on the governor and pullable by the rightful recipient
- Every recipient gets the same protection (protocol, agent, co-proposers, vault owner)
test/governor/FeeBlacklistResilience.t.sol.
Safety: performanceFeeBps is capped by maxPerformanceFeeBps (governor parameter). protocolFeeBps is capped at 1000 bps (10%). managementFeeBps is capped at 1000 bps (10%) and set at the factory level.
Why a management fee? Without it, there is no incentive to operate a vault — the owner curates agents, manages targets, sets parameters, handles emergencies, but earns nothing. The management fee aligns vault owner incentives with depositor outcomes (owner only earns on profit).
Single Strategy Per Vault
Only one strategy can be live (Executed state) per vault at a time. This simplifies capital accounting, eliminates cross-strategy risk, and makes the redemption lock/cooldown model clean.- Governor tracks
activeProposal[vault]— the currently executing proposal ID (0 if none) executeProposalreverts ifactiveProposal[vault] != 0executeProposalalso reverts if the vault is in its cooldown window- Multiple proposals can be in Pending/Approved state simultaneously — they queue up
- Only one can be executed at a time
Open Design Questions
Strategy Carry Model
Two possible models: A. Per-proposal performance fee (current design)- Agent sets fee when proposing
- Fee paid on settlement from profits only
- Simple, clear, hackathon-ready
- Strategy creators earn ongoing % of all TVL running their strategy
- More DeFi-native (like Uniswap LP fees)
- Needs TVL tracking, streaming payments, strategy template integration
What Happens if a Strategy Loses Money?
- Agent earns nothing (performance fee only applies to profits)
- Loss is socialized across all shareholders (standard fund behavior)
- Loss is recorded on-chain via the
ProposalSettled(proposalId, pnl, totalFee)event emitted by_finishSettlement— indexers can aggregate into per-agent track records. A dedicatedSTRATEGY_PNLEAS attestation for richer agent reputation is planned for V1.5 and is NOT shipped in V1. - No slashing mechanism in V1 for agents — see Guardian Review for the separate guardian / vault-owner slashing layer.