-
Notifications
You must be signed in to change notification settings - Fork 0
05 policy lifecycle
Actions edited this page Feb 19, 2026
·
42 revisions
Policies move through a two-step lifecycle:
- request stage (
PolicyDraftcreated), - bind stage (
PolicyMetadatastored and active for claims).
This split allows stake-backed readiness checks between request and activation.
PolicyManager.PolicyStatus:
-
None- no draft exists. -
Created- draft created viarequestCoverage. -
Cancelled- draft cancelled by the requesting covered vault/buyer before binding. -
Bound- policy bound and active metadata persisted.
stateDiagram-v2
[*] --> None
None --> Created: requestCoverage()
Created --> Cancelled: cancelPolicyDraft()
Created --> Bound: CoverPool.bindPolicyForRequest() -> PolicyManager.bindPolicy()
Bound --> [*]
Cancelled --> [*]
Entry: Covered vault (or its adapter, recorded as buyer) calls PolicyManager.requestCoverage(...).
Recommended adapter-based tuple:
-
buyer: covered vault or adapter, -
claimer: adapter, -
beneficiary: adapter, -
bindPolicyHook: adapter (for post-bind cap/config sync).
Checks:
- pool is factory-registered,
- non-zero beneficiary/claimer/payout token,
- non-zero coverage amount and duration,
- hook address supports
IBindPolicyHook.
Effects:
- new
policyIdreserved, -
PolicyDraftstored with statusCreated, - Core committee created with id =
policyId, - curator added as committee operator.
Entry: The requesting covered vault/buyer calls cancelPolicyDraft(policyId).
Checks:
- draft exists and is
Created, - caller is draft buyer (the requesting covered vault/adapter).
Effects:
- status becomes
Cancelled, - no policy metadata is created.
Entry: Curator (pool admin) calls CoverPool.bindPolicyForRequest(...).
- draft exists and belongs to this pool,
- draft status is
Created, - quote pool and policy id match draft,
- quote beneficiary matches draft beneficiary,
- quote timing and expiration valid,
- quote signature valid under
QUOTE_SIGNER_ROLE.
-
SpecRegistry.registerSpec(specId, spec)called by pool. -
StakeManager.addCommitteeVaults(policyId, vaults[])binds committee backing vaults.
PolicyManager.bindPolicy(...) validates:
- caller is pool and pool is factory-registered,
- request data matches draft values,
- duration matches quote window,
- committee has at least one vault,
- operator committee stake >= requested
coverageAmount, - policy commit is unique.
Then it:
- marks draft as
Bound, - stores canonical
PolicyMetadata, - triggers
IBindPolicyHook.onPolicyBound(policyId, coverageLimit)(typically adapter callback).
A bound policy is claimable only during:
-
startTime <= block.timestamp <= maturityTime.
Claims outside this window revert in ClaimManager.
Entry: adapter (as authorized claimer) calls ClaimManager.fileClaim(...), typically on withdrawal-time shortfall detection.
Checks:
- policy metadata exists,
- caller equals metadata
claimer, - requested amount > 0 and <= remaining coverage,
- evidence hash non-zero,
- claim is inside coverage window.
Evaluation and resolution:
- resolve spec by
(pool, specId), - evaluate spec with current context,
- if non-payable -> claim rejected,
- if payable -> slash and settle payout to configured beneficiary (typically adapter).
-
policyIdremains the canonical committee id for all Core interactions. - one draft -> one bound policy metadata record.
- cumulative payouts per policy cannot exceed
coverageLimit, - each claim request is capped by current remaining coverage.
- quote signature domain is pool-specific (
quoteDomainSeparator), - policy commits are unique and cannot be re-registered.
- Verify pool registration before request.
- Verify stake readiness before bind attempts.
- Ensure vault list is valid and non-empty at bind.
- Ensure bind hook address is ERC165-compatible.
- Ensure swap routes are configured before enabling live claim payouts.