// Docs

Architecture

The contracts, what each one is for, and how they fit together.

Components

ContractResponsibility
UnivaultERC-4626 core: shares, NAV, deposit, redeem, and the high-water-mark fee accounting
BasketAdapterHolds the equity basket and executes its trades
PriceOraclePrices holdings in USD and reports staleness
KeeperGuardEnforces every limit before a keeper action runs
ExitRouterSells a whole position, equities included, to USDG in one transaction
BuybackModuleConverts fee revenue into $UNIVAULT and burns what it buys
user --deposit--> Univault --+--> lending vault   (stablecoin leg)
                              |   external ERC-4626
                              +--> BasketAdapter   (equity leg)
                                        ^
keeper --> KeeperGuard ------------------+

user --exit--> ExitRouter --> Univault.redeemInKind + v4 swaps --> USDG

There is no separate YieldAdapter or FeeController contract. The lending leg is an external ERC-4626 vault the Univault supplies into directly, and fee accounting lives inside Univault — fewer moving parts, and fewer contracts you have to read to know what happens to your money.

Why it is split up

Adapters exist so the vault does not know or care which lending market or which venue it is using — swapping one out is a deployment, not a rewrite. The guard is separate so the rules governing automation can be read and reasoned about on their own, without picking them out of the vault's accounting logic.