Skip to main content
See /concepts/shields for the products themselves, and /concepts/triggers for how a trigger reaches the adapter.
A Flash Shield Adapter (FlashShieldAdapter) is a thin UUPS-upgradeable proxy that sits in front of every V5.4 flash shield. Its only job is to expose the legacy IShieldV2 surface that PolicyManagerV2 was built against, while delegating the actual condition logic to the slim BaseFlashShield underneath.

Why the adapter exists

V5.4 introduced BaseFlashShield (sprint T-30a): a slim, common implementation that all 6 flash shields share. The new surface is narrower than IShieldV2 — it doesn’t carry triggerProbBps, old-style asset enum fields, or the per-shield admin functions PolicyManagerV2 calls during purchasePolicyFor / recordTrigger. Two choices were available:
  1. Migrate PolicyManagerV2 to the new ABI — but PM is the most-integrated contract in the protocol (router, indexer, agents-API, SDK, dashboards all read it). A breaking ABI change there would force every downstream to redeploy in lockstep.
  2. Insert a tiny adapter that bridges legacy IShieldV2 → BaseFlashShield per shield. The PM surface stays identical; the slim shield gets its clean ABI; the adapter is the only thing that knows both.
The adapter was chosen (T-30b adapter pattern decision). This is the canonical seam between V5.2-era integrations and V5.4-era shield internals.

Where the adapter sits

When you read PolicyManagerV2.productShield(productId), you get the adapter address, not the underlying BaseFlashShield. Calls land on the adapter, which decodes the legacy ABI and forwards to the slim shield. Most agents never need to touch the inner BaseFlashShield directly — but the address is published (see below) for verifiability.

Properties

The 6 adapters (Base mainnet, V5.4)

Calling pattern from an agent

You almost never call the adapter directly. The flow that matters:
  1. Purchase. CoverRouterV2.purchasePolicy(productId, …) → PM looks up productShield(productId) → calls the adapter, which forwards to BaseFlashShield.recordPolicy(...).
  2. Trigger. ShieldKeeper (or any caller) calls adapter.submitTrigger(payload, signature). The adapter forwards to BaseFlashShield.submitTrigger(...) for the actual signature + sequencer + drop checks. On accept, the base shield calls BondVault.mint(...).
For 99% of agents the adapter is transparent — read productShield(productId) on PM, treat the returned address as “the shield”, call submitTrigger on it. To confirm an adapter is wired to the expected BaseFlashShield:
The first call should return one of the six adapter addresses in the table above. The second should return the matching BaseFlashShield.

Upgradeability and safety

Because the adapter is UUPS, governance can upgrade the legacy-ABI translation layer without touching the underlying shield (e.g. add a new field to the legacy ABI, change the way oracle proofs are routed) — and vice versa. Each adapter has its own upgrade timelock; an upgrade to one adapter does not affect the other five.

See also