-
Notifications
You must be signed in to change notification settings - Fork 0
02 smart contracts
Coverage contracts are the policy and payout application layer over Catalysis Core. They are responsible for policy issuance semantics, premium collection/routing, and claim execution, while Core handles committee stake and SSP-level execution.
graph LR
CPF[CoverPoolFactory]
CP[CoverPool]
PM[PolicyManager]
CM[ClaimManager]
PC[PremiumCollector]
PRM[PremiumManager]
SR[SpecRegistry]
SW[Swapper]
UV3[UniswapV3Adapter]
CPF --> CP
PM --> CP
CP --> PM
CP --> SR
PM --> CM
PC --> PRM
CM --> SR
CM --> SW
SW --> UV3
Role: Deploys and tracks CoverPool clones.
Pattern and state:
- UUPS upgradeable proxy.
- Deploys deterministic minimal proxy clones using
Clones.cloneDeterministic. - Maintains an internal pool set and pagination helpers.
Key functions:
-
createCoverPool(params)creates and initializes a pool clone, grants curator ownership. -
computeCoverPoolAddress(params)predicts deterministic clone address. -
coverPoolExists(pool)validates whether a pool is factory-created.
Note: On EigenLayer, duration vaults act as operators and are auto-deployed during committee creation.
Key role:
-
CREATOR_ROLEcontrols pool creation and major factory settings.
Role: Curator-owned underwriting pool for quote validation and policy binding.
Pattern and state:
- Intended for minimal-clone deployment.
- Uses
AccessControlDefaultAdminRulesUpgradeablefor admin transfer safety. - Maintains bound policy commits and per-policy bound metadata.
Key functions:
-
bindPolicyForRequest(policyId, quote, spec, vaults, signature)performs:- draft checks via
PolicyManager, - EIP-712 quote signature verification,
- spec registration in
SpecRegistry, - committee vault binding in Core via
StakeManager, - final policy bind callback into
PolicyManager.
- draft checks via
-
setPoolFeeBps(...),setFeeRecipient(...)configure pool economics.
Key role:
-
QUOTE_SIGNER_ROLEdefines trusted quote signers.
Role: Policy draft and bound-policy authority.
Pattern and state:
- UUPS upgradeable proxy.
- Stores draft records (
PolicyDraft) and canonical bound metadata (PolicyMetadata). - Tracks next policy id and policy commit uniqueness.
Key functions:
-
requestCoverage(...):- called by the covered vault (or its adapter) as the
buyer, - commonly sets
claimerto the cover adapter, - commonly sets
beneficiaryto the cover adapter for atomic shortfall top-ups, - validates pool and hook,
- creates policy draft,
- creates Core committee with
committeeId = policyId(createCommitteeauto-assigns the pool curator as committee operator).
- called by the covered vault (or its adapter) as the
-
bindPolicy(request, boundPolicy):- callable by pool only,
- validates request/draft/quote consistency,
- verifies stake and vault readiness through Core,
- stores canonical policy metadata,
- calls
IBindPolicyHook.onPolicyBound(policyId, coverageLimit).
Role: Collector of ERC-4626 vault shares and periodic redeemer/distributor.
Pattern and state:
- UUPS upgradeable proxy.
- Tracks registered vault configs: underlying token, pool, policyId, and distribution timestamp.
- Supports keeper-style public batch distribution.
Key functions:
-
registerVault(vault, pool, policyId)maps a covered vault to routing metadata. -
distributeBatch(vaults)redeems shares to underlying and forwards assets toPremiumManager. -
getDistributableVaults()surfaces vaults eligible by interval and balance.
Role: Premium split and restaker reward routing bridge into Core.
Pattern and state:
- UUPS upgradeable proxy.
- Holds platform configuration:
platformTreasury,platformFeeBps.
Key functions:
-
distributePremium(pool, policyId, premiumToken, amount):- computes split: platform / pool / restaker,
- transfers platform fee to treasury,
- transfers pool fee to pool fee recipient,
- retains restaker share (SSPRouter pulls it directly via allowance),
- calls
RewardsManager.distributeRewards(policyId, operator, amount, token).
-
approveSpender(token, spender, amount)grants SSPRouter an allowance to pull the restaker share. -
getFeeSplits(...)deterministic split helper.
Key role:
-
PREMIUM_COLLECTOR_ROLEgates premium distribution entrypoint.
Role: Claim execution engine from filing to payout.
Pattern and state:
- UUPS upgradeable proxy.
- Maintains per-policy claim counters, claim records, and cumulative paid-out amount.
Key functions:
-
fileClaim(policyId, requestedAmount, evidenceHash, additionalData):- acts as a file-and-resolve entrypoint (single transaction),
- validates coverage window and remaining coverage,
- requires caller equals policy
claimer, - resolves spec and runs evaluation,
- if payable, executes slashing and collateral processing,
- transfers payout to beneficiary.
-
remainingCoverage(policyId)and read models for claims.
Slashing and payout mechanics:
- Converts requested payout token amount to USD via Core
ChainlinkPriceFeed. - Calls Core
SlashingManager.executeSlashing(committeeId, operator, slashAmountUSD). - Processes returned collateral token arrays:
- direct transfer if already payout token,
- otherwise swap through
Swapper.
Role: Immutable-style mapping of (coverPool, specId) to ISpec, with admin-controlled spec approval.
Pattern and state:
- UUPS upgradeable proxy.
- Registration is idempotent for the same target and rejects remapping to a different spec.
- Enforces caller is a factory-created pool.
- Maintains an admin-approved whitelist of
ISpecimplementation addresses. A spec must be approved before any pool can register it.
Key functions:
-
approveSpec(spec)called by admin to whitelist a trustedISpecimplementation. -
revokeSpec(spec)called by admin to remove anISpecfrom the whitelist. -
isSpecApproved(spec)view helper to check whether a spec is currently approved. -
registerSpec(specId, spec)called by pool during bind; reverts withSpecNotApprovedif the spec is not on the whitelist. -
resolveSpec(pool, specId)called byClaimManager; resolution is not gated by approval status so in-flight claims on existing policies are unaffected by revocations.
Role: Controlled token conversion path for claim collateral.
Pattern and state:
- UUPS upgradeable proxy.
- Route registry keyed by
(tokenIn, tokenOut). - Supports whitelisted swap targets and native wrapper semantics.
Key functions:
-
setSwapRoute(...),setSwapTargetWhitelist(...)for configuration. -
executeSwap(params)for authorized executors (typicallyClaimManager).
Key roles:
-
SWAP_MANAGER_ROLEconfigures routes and whitelisted targets. -
SWAP_EXECUTOR_ROLEcallsexecuteSwap(held byClaimManager).
Role: Bridges the Swapper's static-calldata pattern to Uniswap V3 SwapRouter02.
Why it exists: The Swapper stores one static calldata blob per (tokenIn, tokenOut) route and
replays it verbatim on every swap. Uniswap V3's exactInputSingle requires the amountIn to be
encoded in each call, making a direct route impossible. The adapter resolves amountIn dynamically
from the allowance the Swapper grants it.
Integration pattern (called by Swapper._performSwap):
- Swapper approves adapter for
amountInoftokenIn. - Swapper calls
adapter.swap(tokenIn, tokenOut, fee, amountOutMinimum)via stored static calldata. - Adapter reads
allowance(Swapper, adapter)to obtainamountIn. - Adapter pulls
tokenInfrom Swapper viatransferFrom. - Adapter calls
SwapRouter02.exactInputSingleforwardingamountOutMinimumfor router-level slippage enforcement. - Router delivers
tokenOutdirectly to Swapper. - Adapter clears residual approval to the router.
Slippage protection: The amountOutMinimum parameter is forwarded directly to the Uniswap V3
router, enabling defense-in-depth slippage protection at the adapter level.
Access control: swap() is restricted to the SWAPPER address recorded at construction time.
Only the authorized Swapper contract may invoke the adapter, enforcing the principle of least
privilege. Any third-party call is rejected with UnauthorizedCaller().
Deployment: script/DeployUniswapV3Adapter.s.sol deploys the adapter (passing the SWAPPER
address as a constructor argument), whitelists it in Swapper, and configures the route in one
transaction. Since UniswapV3Adapter is an immutable contract, any change to the adapter requires
deploying a new instance and reconfiguring the Swapper route via setSwapTargetWhitelist +
setSwapRoute.
| Network | SwapRouter02 |
|---|---|
| Sepolia | 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E |
| Mainnet | 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 |
These components typically live outside this repository but are first-class architecture actors.
- user-facing insured vault,
- sets management-fee style premium parameters (via curator controls),
- allocates/deallocates through the adapter.
- ERC-4626 wrapper around a Morpho vault,
- accrues and collects premiums from depositors,
- tracks reference accounting for shortfall detection,
- calls Coverage claim entrypoints (
fileClaim) on shortfall, - receives claim payout and tops up withdrawals to make depositors whole.
- underlying yield venue where adapter actually places capital,
- can be shared with uninsured users outside the covered vault.
All major contracts are UUPS upgradeable (except CoverPool clones, which are minimal proxies).
Typical control planes:
-
DEFAULT_ADMIN_ROLEfor contract-wide configuration and upgrades. - specialized roles for restricted entrypoints:
-
CREATOR_ROLEon factory, -
QUOTE_SIGNER_ROLEon pools, -
PREMIUM_COLLECTOR_ROLEon premium manager, -
SWAP_MANAGER_ROLE/SWAP_EXECUTOR_ROLEon swapper.
-
- On
SpecRegistry,DEFAULT_ADMIN_ROLEadditionally controls the spec approval whitelist (approveSpec/revokeSpec). Only admin-approvedISpecimplementations may be registered by cover pool curators.
Coverage contracts rely on Core interfaces:
-
IStakeManagerfor committee create/operator/vault and stake reads, -
IRewardsManagerfor reward fan-out trigger, -
ISlashingManagerfor committee slashing execution, -
IChainlinkPriceFeedfor payout-to-USD conversion.