Virtual balances and real inventory
Aqua's per-strategy ledgers price quotes. Only the ERC-20 balance and allowance can settle them.
AquaQoS depends on keeping three quantities apart. Confusing them is how shared liquidity turns into failed settlement, and how a dashboard turns virtual depth into imaginary capital.
| Quantity | Where it lives | What it tells you |
|---|---|---|
| Virtual balance | Aqua, per maker, app, strategy hash and token | How deep this strategy quotes |
| Real balance | The token contract: balanceOf(vault) | What actually exists |
| Allowance | The token contract: allowance(vault, Aqua) | What Aqua is allowed to pull |
Transferable inventory is the smaller of the last two. The vault computes it directly:
function inventory(address token) public view returns (uint256) {
_validateToken(token);
uint256 balance = IERC20(token).balanceOf(address(this));
uint256 allowance = IERC20(token).allowance(address(this), address(AQUA));
return balance < allowance ? balance : allowance;
}How Aqua moves each one
| Operation | Virtual ledger | Real tokens |
|---|---|---|
ship | Records balances for a new strategy | None moved; no backing or allowance is checked |
pull | Reduces the calling app's strategy balance | safeTransferFrom(maker, to, amount) |
push | Increases a strategy's balance; anyone may call it | Transfers from the caller to the maker |
dock | Marks the strategy docked | None moved |
rawBalances returns an amount and a token-count marker: 0 means unregistered and 255
means docked. The mapping has no onchain enumeration, so a scheduler cannot discover every
strategy by itself. The AquaQoS vault keeps an explicit, bounded list of at most eight
strategy hashes instead.
Virtual depth is not owned capital
In the benchmark, raw and guarded policies advertise the full backing B on every
strategy, so aggregate virtual depth is N × B. The real backing is still B. Never read
advertised capacity as money the maker holds.
Why allowance matters
Some standard tokens decrement even a maximum approval. After enough trading, a permissionless
Aqua.push can restore a strategy's virtual entitlement and the real balance, but it cannot
restore the vault's allowance. A policy that checked only balances could admit a fill whose
backing Aqua is no longer allowed to pull.
AquaQoS therefore treats the allowance as part of capacity and keeps a full guarantee
allowance floor on every guarded output. The capacity model
gives the exact rule. This floor addresses an issue found during internal review: Aqua.push
can restore virtual entitlement without restoring the token allowance needed to settle it.