Skip to content

Core invariant

ELI5: The flywheel promises that votes, keepers, and routers cannot steal your collateral or change your loan. They can only move money the protocol already earned or already seized from insolvent positions.

The invariant (exact wording)

No vote, keeper, admin, or caller may move a solvent user's collateral, mint on a bad price, or alter live debt. Routers only move value already released or earned.

What this covers

Actor Allowed Forbidden
Liquidator liquidate when HF < 1 Touch solvent collateral
settle_bad_debt Seize insolvent collateral Change solvent debt
CoilFeeRouter Split harvested fees Pull from CDP
GaugeWeightRouter set_allocations within caps Move user CDP collateral
SurplusSplitter Split donated/earned surplus Mint on bad oracle
TareEngine owner List collateral, pause mint Move solvent user deposits

Scope limits — read carefully

TARE engine ≠ Keep vault

The "no admin in value path" claim applies to TareEngine — no owner function reaches a solvent position's collateral or debt.

Keep has DEFAULT_ADMIN_ROLE and STRATEGY_MANAGER_ROLE on the depositor value path. Those roles must be timelock/multisig. Documented residual risk.

Gauge scope (COMP-2)

GaugeWeightRouter holds ALLOCATOR_ROLE — gates only set_allocations, not full strategy manager powers.

Oracle halt = no bad mints

Pricing halts when feeds disagree or go stale (oracle_lib). The engine reverts rather than minting against a manipulated price.

Flywheel connection

Every router doc links back here:

See Trust model and Composition seams.

What can go wrong

What the invariant does NOT promise

  • Keep strategy manager compromise → depositor fund risk
  • Solver misbehavior on Coil → settlement failures, not CDP theft
  • Smart contract bugs → invariant is intent, not formal verification on mainnet
Deep dive: seized collateral only

withdraw_seized moves collateral already taken via settle_bad_debt, tracked in seized_collateral — not live user deposits.