Owner-only setter. Mainnet deployments delegate ownership to an external TimelockController so changes are visible on-chain before they execute.
The vault has two owner-only setters that take effect immediately on the metavault:
setProtectionPremiumRate(newRateBps): the senior→junior premium rate. Capped at 100% APR.setPerformanceFeeRate(newRateBps): the performance fee, charged only on positive value moves. Hard-capped at 20%.Both run a full accrual sync first, so the rate that applies to the period before the call is the old rate, and the period after the call is the new rate. Holders never under- or over-pay across a cutover.
A third setter, setFeeRecipient(newRecipient), points the performance fee at a different address. Already-minted fee shares stay with whoever held them at mint time.
The metavault itself does not buffer rate changes. setProtectionPremiumRate writes the new rate atomically. To make rate changes visible on-chain in advance of activation, deployments set the metavault's owner to an OpenZeppelin TimelockController. Anyone can read the controller's getMinDelay() to learn the configured wait, and queued operations show up in the controller's CallScheduled events.
What this means in practice:
ProtectionPremiumRateUpdated / PerformanceFeeRateUpdated event when the rate actually changes, plus any TimelockController scheduling events upstream.Senior holders bought into the contract assuming a particular premium rate. A timelocked owner gives senior holders time to:
It also gives indexers and frontends time to re-derive expected APYs and surface the upcoming change.
The performance fee is charged only on positive value moves (never on losses) and paid out as freshly-minted junior shares to the fee recipient, sized so existing junior holders' share price is unaffected by the mint.
The fee recipient address is updated through setFeeRecipient, which (like the rate setters) is owner-only and takes effect immediately on the metavault. The TimelockController in front of the owner is what gates the call.