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

       PolicyManagerV2 (unchanged IShieldV2 ABI)

                │ productShield(productId) → ADAPTER address

       FlashShieldAdapter  (UUPS proxy, IShieldV2)

                │ delegates to

       BaseFlashShield (slim V5.4 logic)


       LuminaOracleV2  /  PolicyManagerV2  /  BondVault
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

PropertyValue
PatternUUPS upgradeable (one proxy per product)
SurfaceIShieldV2 (legacy) — submitTrigger, productId, payoutRatioBps, etc.
BackingOne BaseFlashShield instance per adapter
OwnerGovernance (same multisig as the rest of the protocol)
Upgrade scopeAdapter-only; upgrading the adapter does not redeploy the underlying shield, and vice versa

The 6 adapters (Base mainnet, V5.4)

ProductAdapter (what PM points to)Underlying BaseFlashShield
Flash BTC 1h0x5d50310B9166184e822cD5368F51C1409713054f0x7d1615C90d01712a3b86Df26312aC6D8EFa0d0b3
Flash BTC 24h0x475b3F712707F61824122a94fE78b106260F88820x18e2D3b8Ff4D194CDB9862f8e6239E5e1145961d
Flash BTC 48h0xdc6387E86F7D852D1f99F4009cFd8AdC2d5002980xe206dd8fb02b1C2A0507566c3d03a27554E8CBeB
Flash ETH 1h0x57869AD3E7C56B0c96F357179DD231b407C883380xfF1a1B20153019C22f97278204Ccfc1b1409a518
Flash ETH 24h0x4fD09cF98F6814Cc8b33C2E491429f59d0bCf0890x2832b5543f6F2a055312654739F0ae03F5b0b582
Flash ETH 48h0x9696CFFD7dE8B1e16F83Dcc798c5CE69a61C884C0x60dFC6610c64aC84e12afA943737Cf7733215B75

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:
# 1. Get the adapter address PM is pointing to:
cast call $POLICY_MANAGER 'productShield(bytes32)(address)' \
  $(cast keccak 'FLASHBTC1H-001') --rpc-url $BASE_MAINNET_RPC

# 2. Ask the adapter which BaseFlashShield it forwards to:
cast call $ADAPTER 'implementation()(address)' --rpc-url $BASE_MAINNET_RPC
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