How it Works
How it works
The lifecycle of a deposit
1. You deposit USDC ──▶ Vault ──▶ Manager
(mints you shares)
2. Capital is deployed Manager ──▶ offchain trading strategy
(via whitelisted addresses)
3. Results are reported offchain engine ──▶ Yield ──▶ Vault
(share price moves)
4. You request an exit requestRedeem() — shares burned, amount locked
5. Cooldown elapses (1 day by default)
6. Capital returns Manager ──▶ Vault
(operator-triggered)
7. You collect redeem() ──▶ USDC to youSteps 3 and 6 depend on offchain actors. Everything else you control yourself.
The three contracts
The protocol is three upgradeable contracts, each with one job.
Vault (townSqToken)
The ERC-4626 token you interact with. It mints and burns shares, tracks redemption requests, and maintains the accounting that determines the share price. It deliberately does not hold assets — deposits pass straight through to the Manager.
Because of this, totalAssets() is a bookkeeping number (virtualAssets minus profit that has not vested yet), not a balance you can verify by looking at the vault's token holdings.
Manager
Custodies every deposited asset and deploys capital into the strategy. Two flows matter to you:
Out: an operator calls
execute()to send capital to whitelisted destinations. This is how funds reach the offchain trading book.In: an operator calls
transferToVault()to push assets back so redemptions can be paid.
The Manager also enforces an allowlist — capital can only be sent to addresses that governance has explicitly whitelisted.
Yield
Receives the offchain engine's profit and loss reports and applies them to the vault. It handles profit vesting, loss application, and the treasury's performance fee.
Where the yield comes from
Not from onchain lending or liquidity provision. Capital is transferred to an offchain trading counterparty, and returns are generated by that counterparty's trading activity.
This has two consequences worth being explicit about:
The strategy's performance is not visible onchain. The vault has no view of the trading book. What you see is the reported result.
Recovering capital depends on the counterparty performing. Once assets leave via
execute(), the enforcement is contractual and offchain, not onchain.
This is the single most important structural fact about the protocol. See Risks and trust assumptions.
How results reach you
An offchain engine calls distributeYield(amount, feeAmount, nonce, isProfit) once per epoch — at most roughly once every 22 hours by default.
amountis the shareholders' slice.feeAmountis the treasury's slice, on top ofamount, not carved out of it.isProfitsets the direction.
On profit: amount is released into the share price linearly over the vesting period (7 days by default), rather than all at once. This prevents someone from depositing just before a report and capturing yield they were not exposed to.
On loss: the loss applies immediately, with no vesting. Profit that has not vested yet absorbs the loss first — if the loss is smaller than the unvested buffer, the share price does not move at all.
Each report is bounded: by default no more than 0.5% of vault assets per epoch, and epochs must be at least ~22 hours apart. Both limits are governance-adjustable.
Last updated