-
Notifications
You must be signed in to change notification settings - Fork 0
03 core integration
Coverage uses Core as the execution and accounting substrate for restaked security. The boundary is strict:
- Coverage defines underwriting, policy semantics, premium routing, and claim intent.
- Core executes committee-level stake, reward distribution, and slashing on SSP adapters.
This separation keeps restaking platform complexity out of Coverage contracts.
| Coverage Contract | Core Contract | Function | Purpose |
|---|---|---|---|
PolicyManager |
StakeManager |
createCommittee(policyId, pool, duration) |
Create policy-scoped committee scaffold |
PolicyManager |
StakeManager |
addOperatorToCommittee(curator, policyId) |
Explicitly register pool curator as committee operator (called immediately after createCommittee) |
CoverPool |
StakeManager |
setCommitteeVaults(policyId, vaults[], coverageLimit) |
Bind selected vaults/strategies; configures TVL limits on EigenLayer vaults |
PolicyManager |
StakeManager |
getCommitteeVaults(policyId) |
Verify vault backing exists before bind finalization |
PolicyManager |
StakeManager |
getCommitteeTokenStakes(policyId) |
Retrieve per-vault token-native stake amounts for USD sufficiency check |
PolicyManager |
ChainlinkPriceFeed |
getUSDValue(token, amount) |
Convert coverageLimit and committee token stakes to USD for bind-time sufficiency check |
PremiumManager |
RewardsManager |
distributeRewards(policyId, operator, amount, token, taskId) |
Trigger Core reward fan-out; RewardsManager pulls restaker share from PremiumManager, then routes via SSPRouter |
ClaimManager |
SlashingManager |
previewSlashing(committeeId, operator) |
Read per-vault token-native stake amounts before executing |
ClaimManager |
SlashingManager |
executeSlashing(committeeId, operator, VaultSlash[], taskId) |
Execute token-native per-vault slashing and return seized collateral |
Note: EigenLayer operator setup (depositing stake, allocating magnitude, and registering to the committee's operator set) is performed off-chain by the restaker before bind. See Restaker Setup for the full sequence.
Coverage enforces policyId == committeeId across all cross-layer calls.
Implications:
- Capacity is set once at policy request (
coverageAmount). - Vault assignment is attached to the same id at bind time.
- Rewards and slashing are naturally scoped to the policy's committee.
Typical covered-vault actor mapping (CoveredVaultWrapper model):
-
buyer:CoveredVaultWrapper. -
claimer:CoveredVaultWrapper(withdrawal-triggered claim path). -
beneficiary:CoveredVaultWrapper— receives the payout and tops up the withdrawing user atomically.
Sequence:
- Curator invokes
CoverPoolFactory.createCoverPool(params). - Factory deploys and initializes a pool clone with curator as owner.
Outcome:
- Curator is pool owner and holds
DEFAULT_ADMIN_ROLEon the pool. - Pool is tracked in factory for
coverPoolExists()validation.
Sequence:
- Covered vault (or its adapter acting as buyer) calls
PolicyManager.requestCoverage(...). - Manager creates draft and increments
policyId. - Manager calls
StakeManager.createCommittee(policyId, pool, duration). - Manager calls
StakeManager.addOperatorToCommittee(curator, policyId)to explicitly register the pool's curator as committee operator.
Outcome:
- Draft exists in Coverage.
- Committee scaffold exists in Core with policy-aligned id and curator as operator.
Sequence:
- Curator calls
CoverPool.bindPolicyForRequest(...)with quote and vaults. - Pool calls
StakeManager.setCommitteeVaults(policyId, vaults, coverageLimit).-
SSPRouter._configureEigenStrategiesruns internally: adds strategies to operator set, sets TVL limits (convertingcoverageLimitUSD to token-native amounts), and locks duration vaults.
-
-
PolicyManager.bindPolicy(...)checks:- committee has at least one vault (
getCommitteeVaults), -
getCommitteeTokenStakes(policyId)returns per-vault stakes; their USD values (viaChainlinkPriceFeed.getUSDValue) sum to >=coverageLimitUSD-equivalent.
- committee has at least one vault (
Outcome:
- Policy transitions to bound/active state only when Core backing is present and stake is sufficient.
Sequence:
-
CoveredVaultWrapper.collectPremium()flushes accrued premium and callsPremiumManager.distributePremium(...). -
PremiumManagerpulls tokens viasafeTransferFrom, computes fee splits. - Platform fee →
platformTreasury; pool fee → poolfeeRecipient. -
PremiumManagercallsRewardsManager.distributeRewards(policyId, curator, restakerSplit, token, taskId). -
RewardsManagerpulls the restaker share fromPremiumManagerto itself viasafeTransferFrom(premiumManager, address(this), ...)(requires PremiumManager to have approved RewardsManager), then callsSSPRouter.distributeRewards(..., tokenSource=address(this)). -
SSPRouterpulls fromRewardsManagerand fans out to adapters.
Outcome:
- Coverage specifies policy/operator reward intent.
- Core executes final per-SSP reward distribution.
Sequence:
-
CoveredVaultWrapper._settleWithdrawalTransferdetects a shortfall and callsClaimManager.fileClaim(...). -
ClaimManagercallsSlashingManager.previewSlashing(policyId, operator)to get per-vault token-native stake amounts. -
ClaimManager._computeVaultSlashesquotes each cross-token stake viaSwapper.quoteSwap, then computes proportional token-nativeVaultSlash[]amounts, inflating cross-token amounts by1 / (1 - maxSwapSlippageBps)for slippage coverage. -
ClaimManagercallsSlashingManager.executeSlashing(policyId, operator, VaultSlash[], taskId). - Core returns seized collateral token arrays.
- Coverage swaps or directly transfers to beneficiary; surplus collateral is routed to
RewardsManagerviaPremiumManager.forwardRewards.
No USD conversion or price feed is involved in the claim execution path. The only price-feed use in Coverage is at bind time inside PolicyManager._validateStakeSufficiency, which converts the committee's token-native stake to USD and compares it against coverageLimit.
Outcome:
- Core performs SSP slashing mechanics.
- Coverage performs beneficiary-facing settlement;
CoveredVaultWrapperreceives the payout and tops up the user's withdrawal.
No-shortfall withdrawal path:
- If the Morpho vault returns sufficient assets, no claim is filed and no Core slashing call is made.
- Slash amounts passed to
executeSlashingare token-native (not USD);ClaimManagercomputes them viapreviewSlashing+quoteSwap. - Coverage payouts are token-denominated by
payoutToken. -
coverageAmountinPolicyDraftis treated as the committee stake requirement (USD, 8 decimals) for bind-time sufficiency checks only;ChainlinkPriceFeedis used exclusively there.
Coverage assumptions about Core:
- committee state and stake reads are correct and timely,
- reward/slash execution either succeeds or reverts atomically,
- token arrays returned from slashing are valid and aligned.
Failure patterns:
- If Core stake is insufficient at bind check, policy bind reverts.
- If slashing returns empty arrays, claim payout reverts.
- If price feed conversion fails or is stale, policy bind path fails (bind-time stake sufficiency check).
- Keep
policyIdand committee references consistent in all off-chain orchestration. - Ensure restakers have deposited into the committee's duration vault before bind. Duration vaults act as EigenLayer operators — no separate magnitude allocation or operator-set registration is needed. See Restaker Setup.
- Register and verify vault module mappings in Core (
SSPRouter.registerVaultModule) before bind. - Configure swap routes for expected collateral → payout token pairs before claims;
Swapper.quoteSwapis used at claim time for slippage computation. -
WETHprice feed must be registered inChainlinkPriceFeedbefore binding policies whose payout token is WETH (stake USD sufficiency check at bind).