Multi-Vault Staking Runtime Flow
This note describes the current vaultId-based runtime behavior for staking, minting, redemption, and hedger liquidity flows.
Core Runtime State
QuantillonVault tracks:
defaultStakingVaultIdstakingVaultAdapterById[vaultId]stakingVaultActiveById[vaultId]redemptionPriorityVaultIds[]stQEUROTokenByVaultId[vaultId]principalUsdcByVaultId[vaultId]totalUsdcHeldtotalUsdcInExternalVaults
Mint and Stake Flows
1) Mint (default routing)
mintQEURO(usdcAmount, minQeuroOut)calls internal mint flow withdefaultStakingVaultId.- If default vault id is non-zero and valid, net USDC is auto-deployed to that vault adapter.
- If default vault id is
0, net USDC remains intotalUsdcHeld.
2) Mint (explicit vault)
mintQEUROToVault(usdcAmount, minQeuroOut, vaultId)uses providedvaultId.
3) Mint + Stake (one-step)
mintAndStakeQEURO(usdcAmount, minQeuroOut, vaultId, minStQEUROOut):- Mints QEURO via the same vault-aware mint flow.
- Resolves
stQEUROTokenByVaultId[vaultId]. - Stakes and transfers stQ token to caller.
Auto-deploy implementation
_mintQEUROCommitmoves net amount from held balance to per-vault principal accounting whentargetVaultId != 0._autoDeployToVault(vaultId, usdcAmount)deposits through configured adapter and emitsUsdcDeployedToExternalVault.
Yield Distribution to Stakers
harvestAndDistributeVaultYield(vaultId) (YIELD_DISTRIBUTOR_ROLE) realizes the adapter's accrued
yield into the vault and splits it three ways: hedger funding first (absolute, time-prorated on
the deployed notional), then the staked-user share credited into stQEURO via creditVaultYield
(rising share price), then the remainder to treasury. This is the path that actually rewards
stQEURO holders. See Staking Yield Distribution for the full
model, parameters (fundingRateAnnualBps, hedgerYieldRecipient), and operator runbook.
Redemption Flow
redeemQEURO(qeuroAmount, minUsdcOut) (normal mode):
- Computes required USDC and checks total collateral availability.
- Uses
_planExternalVaultWithdrawal(requiredUsdc)to compute deficit vstotalUsdcHeld. - Commit phase withdraws deficit through
_withdrawUsdcFromExternalVaultswhen needed.
Withdrawal source order:
- First:
redemptionPriorityVaultIds(if configured). - Fallback: single-item array with
defaultStakingVaultId. - If neither exists and held balance is insufficient, redemption reverts (
InsufficientBalance).
Liquidation-mode redemption uses the same external-withdraw planning pattern.
Hedger Flow
Hedger opens / adds margin
HedgerPooltransfers USDC intoQuantillonVault.vault.addHedgerDeposit(...)increasestotalUsdcHeld.
Hedger closes / removes margin / liquidation payout
HedgerPoolcallsvault.withdrawHedgerDeposit(...).- Vault uses held USDC first; if needed, it withdraws from external vaults using the same priority logic as redemptions.
Governance and Operator Controls
QuantillonVault controls:
setStakingVault(vaultId, adapter, active)(GOVERNANCE_ROLE)setDefaultStakingVaultId(vaultId)(GOVERNANCE_ROLE)setRedemptionPriority(vaultIds[])(GOVERNANCE_ROLE)harvestAndDistributeVaultYield(vaultId)(YIELD_DISTRIBUTOR_ROLE) — harvest + 3-way split to stakers/hedger/treasurycreditVaultYield(vaultId, usdcAmount)(YIELD_DISTRIBUTOR_ROLE) — credit USDC into stQEURO as QEURO backingsetFundingRateAnnualBps(bps)/setHedgerYieldRecipient(addr)(GOVERNANCE_ROLE)deployUsdcToVault(vaultId, usdcAmount)(VAULT_OPERATOR_ROLE)
Factory binding:
selfRegisterStQEURO(factory, vaultId, vaultName)links vault id to stQ token (GOVERNANCE_ROLE).
Automatic vs Operational Actions
Automatic:
- Mint routing to default/explicit vault (if configured).
- Redemption and hedger withdrawals sourcing liquidity from external vaults when needed.
Operational:
- Adapter configuration and activation.
- Default vault and redemption-priority policy.
- Deploying idle held USDC (
deployUsdcToVault). - Harvesting + distributing adapter yield (
harvestAndDistributeVaultYield).
Key Events for Indexer and Admin Read Models
VaultRegistered(factory)StakingVaultConfiguredDefaultStakingVaultUpdatedRedemptionPriorityUpdatedUsdcDeployedToExternalVaultUsdcWithdrawnFromExternalVaultVaultYieldDistributed(harvest + 3-way split)
Practical Ops Notes
- If
vaultIdconfig is missing/inactive, vault-aware actions revert (InvalidVault/ config errors). - If held + external principal cannot satisfy required payouts, flows revert (
InsufficientBalance). - Correct default and priority setup is critical to predictable redemption behavior.
Source Files
src/core/QuantillonVault.solsrc/core/HedgerPool.solsrc/core/stQEUROFactory.sol