-
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 |
OraclePriceFeed |
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 (
coverageLimit) is set at bind time from the signed quote. - 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: wrapper owner (EOA or multisig).CoveredVaultWrapper._validatePolicyBindingenforcespol.buyer == owner()and reverts if it does not match. -
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:
- The wrapper owner (EOA/multisig) calls
PolicyManager.requestCoverage(...)asbuyer. - 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 (viaOraclePriceFeed.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. -
PremiumManagergrantsRewardsManageran ephemeral per-call allowance viaforceApprove(rewardsManager, restakerSplit), then callsRewardsManager.distributeRewards(policyId, curator, restakerSplit, token, taskId). After the call, the allowance is zeroed withforceApprove(rewardsManager, 0). No standing allowance or adminapproveSpendersetup is required. -
RewardsManagerpulls the restaker share fromPremiumManagerto itself viasafeTransferFrom, 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.distributeSurplusAsRewards.
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. -
coverageLimitinQuote/BoundPolicy/PolicyMetadatais denominated inpayoutTokennative units (not USD). At bind time,PolicyManager.bindPolicyconverts it to USD viaOraclePriceFeed.getUSDValue(payoutToken, coverageLimit)and compares against the committee's total staked USD. This is the only point whereOraclePriceFeedis used in Coverage contracts. ThePolicyDraftstruct does not contain acoverageAmountfield.
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 inOraclePriceFeedbefore binding policies whose payout token is WETH (stake USD sufficiency check at bind).