Tango vaults
Sub-accounts and NAV
How a Tango vault splits a strategy into separate sub-accounts, and how their values add up to the vault's NAV and share price.
A Tango vault does not keep all of its money in one place. It splits the strategy into sub-accounts: separate contracts that each hold one part of the strategy, with their own assets, limits and way of being valued. The vault adds up what each sub-account is worth to get its NAV (net asset value), and that number sets the price of every deposit and withdrawal.
Key points
- Each sub-account is its own contract with its own assets and limits, so one activity cannot spill into another.
- The vault's NAV is its idle USDC plus the value of every sub-account, minus fees it owes. NAV divided by the number of shares is the share price.
- There are two kinds of sub-account. Tracked sub-accounts are valued from onchain prices. Attested sub-accounts are valued from a reported figure that must stay within strict limits.
Why sub-accounts
A strategy often does several things at once. It might hold tokens, lend USDC on Morpho and trade perps on an exchange. If all of that sat in one account, it would share one set of permissions, one way of measuring value and one point of failure.
Sub-accounts keep these activities apart. Each sub-account:
- is a separate contract that holds its own assets;
- has a cap on how much of the vault's money it can hold, and a limit on how fast that can grow;
- has its own list of assets it may hold, or its own list of transactions it may make;
- has its own permission to act, so a key can be limited to a single sub-account;
- is valued in its own way.
Money never moves straight from one sub-account to another. It goes back to the vault first and is then sent out again, so every move passes the limits of the sub-account receiving it.
How NAV adds up
Vault idle USDC: counted from the vault's own records, not its token balance Tracked sub-account: each registered asset's quantity times its oracle price, converted to USDC Attested sub-account: the last accepted reported value, adjusted exactly for USDC sent in or brought back since Accrued fees: management and performance fees earned but not yet paid out, subtracted Vault NAV = idle USDC + tracked values + attested values - accrued fees Share price = NAV / total shares Not counted: pending deposits, USDC already owed to settled withdrawals, tokens sent to any contract without being asked for
The vault works out its NAV fresh every time it settles a deposit or a withdrawal. It never stores an old figure to reuse. A few details make the number hard to push around:
- The vault and its tracked sub-accounts count what they recorded receiving, not whatever tokens sit at their address. If someone sends tokens to a vault without being asked, the NAV does not change. Nobody can move the share price by donating to a vault.
- Every asset is priced in US dollars, added up, and converted to USDC once using the USDC price feed.
- NAV leaves out money that belongs to specific people: USDC waiting in a deposit request, and USDC already set aside for a settled withdrawal.
When NAV is stale
A price is stale when it is too old to trust, for example an oracle price past its update deadline, or a reported value that has not been refreshed in time. If any price the vault needs is stale, the whole NAV is stale. While that lasts:
| Paused | Still works |
|---|---|
| Settling deposits and withdrawals | Requesting a deposit or a withdrawal |
| Forced exits | Cancelling a request |
| One-transaction (atomic) deposits | Claiming requests that were already settled |
| Reading the vault's total value (it reverts instead of returning a wrong number) | Sending USDC to a sub-account that is not frozen |
This is a deliberate brake. Nobody can deposit or withdraw at a price the vault cannot stand behind. It also means settlement can pause, for example while tokenized stock prices are frozen over a weekend. See Tokenized stocks.
Tracked and attested
| Tracked sub-account | Attested sub-account | |
|---|---|---|
| Valued from | Quantities of registered assets times oracle prices | A reported value, used only within a set range |
| Acts through | Built-in modules for swapping, lending and liquidity | A short list of approved transaction types, such as a bridge transfer |
| Can hold | Only registered assets count | Anything; the report values the whole account |
| Can borrow | No | Yes, through approved transactions |
| Each action is checked by | An oracle price check plus policy limits | The approved-transaction list; the next report shows the result |
| Reachable by a forced exit | Yes | No |
| One-transaction deposits | Allowed | Turned off for the whole vault |
Read more in Tracked sub-accounts and Attested sub-accounts.
How many, and when they are added
- Every vault has a maximum number of sub-accounts, fixed when it is deployed. Factories on release 0.12.0 allow up to 3.
- Sub-accounts are usually added when the vault is deployed, through the factory.
- Adding one later is a Critical-level change, which waits 14 days on Tango's production factories. See Timelocks.
- Removing one takes two steps. It is marked for removal right away, and removed once it holds nothing. NAV does not change at either step.
Limits on capital
| Limit | What it caps | To raise it | To lower it |
|---|---|---|---|
| Allocation cap | How much USDC can be sent to a sub-account, minus what it has sent back. Gains do not count against it. | High-level change (7 days), and never above a ceiling fixed at deployment | Immediate |
| Sending limit | How fast USDC can be sent in, like a bucket that refills over time | High-level change (7 days) | Immediate |
Both start at zero, which blocks everything until they are set. See Rate limits for how these limits work and which settings can be adjusted.