Governance & Operations¶
This page covers how the protocol changes over time: spells (the change-management vehicle), the automation managers that run routine operations, the deployment model, and the audit posture. The underlying authority model — Root, timelocks, guardians — is documented in the Security Model.
Spells¶
All privileged protocol changes ship as spells: one-shot governance contracts that batch the privileged actions for a change and can execute exactly once.
Lifecycle¶
1. Deploy the spell contract (its actions are public, auditable code)
2. Guardian → root.scheduleRely(spell)
3. Timelock elapses (48h on mainnet)
4. Anyone → root.executeScheduledRely(spell) [permissionless once due]
5. spell.cast() executes the batched privileged actions
— guarded by a one-shot `done` flag
6. The spell denies itself; it retains no authority
Properties worth noting for reviewers:
- Guardians cannot bypass the timelock. Scheduling is guardian-gated, but execution only becomes possible after the delay, and execution itself is permissionless.
- There is no direct Root access on testnet or mainnet — every privileged change passes through a spell.
- A spell's exact effects are on-chain before the timelock starts, so the community and auditors can review precisely what will execute.
Example¶
A representative migration spell (V2CleaningsSpell) executed a one-shot cast that migrated legacy token wards from a V2 Root to the V3 Root, stripped the V2 Root from legacy tranche tokens, swept a legacy escrow's USDC to the treasury, and relied the ContractUpdater on the four transfer hooks — then denied itself on both Roots. Each step guards on the target's code existence, making the same spell safely portable across chains.
Upstream automation managers¶
Alongside the Arkonix-specific managers (Arkonix Extensions), the protocol ships upstream automation managers that operationalize routine flows. All are unmodified Centrifuge V3.
| Manager | Side | Purpose |
|---|---|---|
NAVManager |
Hub | Computes and pushes pool NAV into accounting and pricing (assumes assets shared across share classes). Exposes netAssetValue, account-ID helpers, and the onSync/onTransfer snapshot-hook entry points; manager-gated |
SimplePriceManager |
Hub | Derives the share price from NAV for single-share-class pools; consumes NAV updates and exposes pricePoolPerShare |
QueueManager |
Spoke | Batches and flushes queued BalanceSheet updates cross-chain, with a configurable minimum delay between syncs |
OnOfframpManager |
Spoke | Per pool/share class (factory-deployed). Permissionless onramp of allowed assets sent to the manager; permissioned offramp — only whitelisted relayers, only to predefined receiver accounts. Registered as a balance-sheet manager |
Deployment model¶
- Deterministic addressing: top-level contract addresses are deterministic across all networks via CREATE3 — the same contract has the same address on every chain. Factories deploy pool-scoped contracts (escrows, vaults, share tokens, proof managers) at deterministic CREATE2 addresses with pool- and share-class-derived salts.
- Factories retain no power: every factory relies
Root(plus required managers) on what it deploys, then denies itself (see core patterns). - The protocol is deployed across multiple EVM mainnets and testnets; a full-stack deployer deploys the complete suite, including the Arkonix proof-manager factories.
- Upstream tracking: because the core is an unmodified Centrifuge V3 fork, upstream changes are merged on a daily cadence, keeping the deployed core aligned with upstream development.
Audits¶
The core contract suite is Centrifuge V3, which has been audited; audit reports are maintained with the protocol repository, and Centrifuge V3.1 additionally ran a public Sherlock audit contest. The Arkonix extension contracts are additive and scoped, which keeps their audit surface small and well-defined.
For Arkonix's overall audit posture, engagements, and published reports, see Audits.
Upgrade and emergency procedures¶
The procedures below follow directly from the mechanisms documented in the Security Model and Messaging pages:
| Situation | Procedure |
|---|---|
| Planned privileged change | Spell through the Root timelock (above) |
| Cross-chain upgrade | ProtocolGuardian scheduleUpgrade(centrifugeId, target) — a cross-chain scheduled rely on a remote Root; ScheduleUpgrade/CancelUpgrade messages are accepted only from mainnet |
| Emergency stop | pause() — instant, callable by any individual owner of the protocol safe; only the full safe can unpause. Pausing halts pauseable operations protocol-wide via the global Root.paused flag |
| Compromised or obsolete permission | deny / denyContract / cancelRely — revocations are instant, never timelocked |
| Halting outbound traffic to a chain | ProtocolGuardian blockOutgoing on the Gateway (also available pool-scoped) |
| Bridge quorum failure | Governance message injection via the RecoveryAdapter and the MultiAdapter's recovery index |
| Stuck funds in a protocol contract | TokenRecoverer — atomic rely → recover → deny, triggered by governance or a mainnet-origin RecoverTokens message |
| Failed inbound message | Permissionless Gateway.retry once the underlying condition is resolved |