Quantillon Protocol

Multi-Vault Staking Runtime Flow

Signed quotes are active on Base since 17 October 2026. See Signed Quotes in Production for verified bindings, transaction wrappers and emergency-mode limits.

This note describes the current vaultId-based runtime behavior for staking, minting, redemption, and hedger liquidity flows.

Core Runtime State

QuantillonVault tracks:

  • defaultStakingVaultId
  • stakingVaultAdapterById[vaultId]
  • stakingVaultActiveById[vaultId]
  • redemptionPriorityVaultIds[]
  • stQEUROTokenByVaultId[vaultId]
  • principalUsdcByVaultId[vaultId]
  • totalUsdcHeld
  • totalUsdcInExternalVaults

Mint and Stake Flows

The conversion selectors below are inner operations. In production signed mode, submit the permitted operation through executeWithQuote(bytes,bytes) with its exact authorization; bare unquoted conversion calls are rejected.

1) Mint (default routing)

  • mintQEURO(usdcAmount, minQeuroOut) calls internal mint flow with defaultStakingVaultId.
  • 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 in totalUsdcHeld.

2) Mint (explicit vault)

  • mintQEUROToVault(usdcAmount, minQeuroOut, vaultId) uses provided vaultId.

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

  • _mintQEUROCommit moves net amount from held balance to per-vault principal accounting when targetVaultId != 0.
  • _autoDeployToVault(vaultId, usdcAmount) deposits through configured adapter and emits UsdcDeployedToExternalVault.

Yield Distribution to Stakers

QuantillonVault 1.6.0 preserves the allocation introduced in 1.5.0 and allocates realized strategy yield by the harvest-time ratio of raw staked QEURO to total QEURO supply. Stakers receive their gross allocation after the configured haircut; treasury receives the unstaked allocation. The hedger receives only that haircut, with no base allocation for hedger collateral. There is no additional staking yield fee on vault credits; conversion costs and admission checks remain.

The release accepts one funded strategy and one outstanding staking series; registered empty strategies are allowed. It rejects unsupported simultaneous allocation. Raw staked QEURO includes unvested credit, while totalAssets() excludes yield not yet redeemable. Shareholders participate pro rata as yield vests; this does not make allocation time-weighted.

The keeper reads yieldDistributionConfig and the on-chain preview. hedgerBase remains zero for ABI compatibility. Older 1.4.x and legacy deployments retain their own models. See Yield Distribution 1.5.0.

Redemption Flow

redeemQEURO(qeuroAmount, minUsdcOut) (normal mode):

  • Computes required USDC and checks total collateral availability.
  • Uses _planExternalVaultWithdrawal(requiredUsdc) to compute deficit vs totalUsdcHeld.
  • Commit phase withdraws deficit through _withdrawUsdcFromExternalVaults when 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

  • HedgerPool transfers USDC into QuantillonVault.
  • vault.addHedgerDeposit(...) increases totalUsdcHeld.

Hedger closes / removes margin / liquidation payout

  • HedgerPool calls vault.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/treasury
  • creditVaultYield(vaultId, usdcAmount) (YIELD_DISTRIBUTOR_ROLE) — credit USDC into stQEURO as QEURO backing
  • setHedgerStakingYieldHaircutBps(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)
  • StakingVaultConfigured
  • DefaultStakingVaultUpdated
  • RedemptionPriorityUpdated
  • UsdcDeployedToExternalVault
  • UsdcWithdrawnFromExternalVault
  • VaultYieldDistributed (harvest + 3-way split)

Practical Ops Notes

  • If vaultId config 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.sol
  • src/core/HedgerPool.sol
  • src/core/stQEUROFactory.sol