Redemption insurance for FXRP β if your redemption agent never delivers XRP, Flare's own on-chain proof pays you make-whole
FAssets let XRP holders bring their asset into Flare DeFi β but the redemption leg (turning
FXRP back into native XRP) is the riskiest step. When you redeem, an assigned agent must send you
XRP by a deadline. If it doesn't, you have to notice the miss, commission a Flare Data Connector
proof yourself, call redemptionPaymentDefault(), and accept collateral compensation at a haircut.
It's manual, slow, and uncertain β and that uncertainty keeps desks and treasuries from redeeming at
size, quietly weakening confidence in the FXRP peg.
Backstop turns that into a one-click guarantee. You buy a guard bound to your on-chain
redemption ticket for a small FTSO-priced premium. An autonomous keeper watches the deadline. If
the agent doesn't pay, anyone can submit Flare's FDC ReferencedPaymentNonexistence attestation
β the exact proof the FAssets protocol itself accepts for a redemption default β and Backstop
verifies it on-chain and pays you make-whole instantly. Underwriters fund the pool and earn the
premiums of every guard whose agent paid on time.
Backstop doesn't re-invent cross-chain trust β it rides Flare's own default mechanism.
- Primary β the FXRP redeemer. Anyone converting FXRP back to native XRP through the FAssets
redemption queue, and especially trading desks and treasuries redeeming at size, for whom a
single agent default is a real balance-sheet event. Concretely: the wallet that calls
AssetManager.redeem()and then has to wait and hope the agent delivers on XRPL. - Secondary β the underwriter (LP). FLR holders wanting yield uncorrelated with token price. They fund the pool, earn redemption premiums, and are protected by an on-chain per-agent exposure cap and a global solvency cap.
- Downstream β FAssets integrators. Lending markets, DEXes and custodians that would rather
quote FXRP redemption risk than absorb it.
buyGuardis callable by any contract β Backstop is a protocol, not just an app.
Six engine-class Flare methods, wired in code and proven on Coston2:
| # | Flare method | Role in Backstop |
|---|---|---|
| 1 | IFdcVerification.verifyReferencedPaymentNonexistence |
the claim gate β proves the agent did NOT pay |
| 2 | IFdcHub.requestAttestation (RPN) |
keeper requests the non-payment attestation |
| 3 | FDC DA-Layer proof fetch | retrieves the finalized proof + Merkle path |
| 4 | IAssetManager.redemptionRequestInfo |
binds a guard to a real FXRP redemption ticket |
| 5 | FtsoV2.getFeedById (XRP/USD, FLR/USD) |
sizes coverage + prices premium/payout |
| 6 | FlareContractRegistry.getContractAddressByName |
resolves everything β nothing hardcoded |
Take Flare out and you'd need four separate systems: a cross-chain XRPL light client, a decentralized "payment-did-not-happen" attestation network, a price oracle, and a canonical FXRP redemption registry. Backstop is ~550 lines of Solidity because Flare enshrines all four β and FDC's non-existence proof is something almost no other chain exposes natively.
flowchart TD
U[Redeemer] -->|redeem FXRP| AM[FAssets AssetManager]
U -->|buyGuard ticket + premium| BS[Backstop]
LP[Underwriters] -->|deposit / withdraw| POOL[BackstopPool]
BS <-->|lock exposure Β· payout| POOL
BS -->|getFeedById XRP/USD Β· FLR/USD| FTSO[FtsoV2]
BS -->|redemptionRequestInfo| AM
K[Keeper β±] -->|watch deadline| AM
K -->|requestAttestation RPN| HUB[IFdcHub]
HUB --> RELAY[Relay Β· Merkle root]
K -->|fetch proof| DA[DA Layer]
K -->|claim guardId, proof| BS
BS -->|verifyReferencedPaymentNonexistence| FDCV[IFdcVerification]
BS -->|make-whole payout| U
FE[Web Β· /integrations/verify] -->|live reads| BS
FE -->|live reads| POOL
classDef flare fill:#0B7A57,stroke:#3ECF9A,color:#fff;
class AM,FTSO,HUB,RELAY,DA,FDCV flare;
Contracts resolve every Flare address through the registry (RegistryResolver); the keeper is a
convenience, not a trust assumption β the claim path is permissionless, so the redeemer or anyone
can submit the proof.
buyGuard β agent misses deadline β keeper requests RPN proof β claim verifies it on-chain β make-whole payout
buyGuard (wallet connected): the premium re-prices live from the FTSO FLR/USD feed as you type β $0.70 β 1.2281 C2FLR, $2.50 β 4.386 C2FLR.
The whole product hinges on one assertion: that the FDC non-existence round-trip actually works on
Coston2. We front-loaded it as a go/no-go gate β scripts/spike.ts exercises
every load-bearing call-site end-to-end and prints PASS/FAIL. Run npm run spike:view (no wallet)
or npm run spike:all (funded).
β PASSED on Coston2 (2026-07-29). All five stages green. The load-bearing leg β
IFdcHub.requestAttestationβ DA-Layer proof βIFdcVerification.verifyReferencedPaymentNonexistenceβ returnedtrueon-chain in 99.3 s (tx0x5774a763β¦9c540a, voting round 1409442). Full benchmark + reproduce steps:DEMO.md.
Beyond the isolated FDC gate, the entire product loop ran live on Coston2 against a genuine FAssets
redemption default β redeem β buyGuard β the assigned agent misses the deadline β keeper proves
non-payment via FDC β claim pays the redeemer make-whole:
β Guard #1 PAID (2026-08-01). Real ticket
redemptionRequestId 42481292(agent0xd5dEβ¦2D64). The keeper reconstructed theReferencedPaymentNonexistencewindow directly from the liveredemptionRequestInfoβ its primary path, not the synthetic fallback β andBackstop.claimpaid 111.55 C2FLR to the redeemer. Claim tx0x5fde024fβ¦(block 33493034). Full tx trail + one-command reproduce (npm run route-b):DEMO.mdΒ·scripts/route-b.ts.
/integrations/verify, live from Coston2 β guard #1 PAID, payout 111.55 C2FLR at block 33493034 (no wallet needed).
| Contract | Address |
|---|---|
Backstop |
0xe7DFfa49EC57f5a9ca349C0F9a170950F052E708 |
BackstopPool |
0x9c1e0f1318141B7dA85207d731157D4853918A9A |
Both source-verified on Blockscout β the exact repo source, including the reentrancy guards and
zero-address checks (Slither: 0 findings). Deploy script: script/Deploy.s.sol.
| Layer | Where | What |
|---|---|---|
| Contracts | src/ |
Backstop (guard lifecycle + claim), BackstopPool (underwriting), PremiumMath, RegistryResolver |
| Keeper | scripts/keeper.ts |
autonomous watcher β detects breaches, requests the RPN proof, submits claim. --once / --dry-run modes (scripts/KEEPER.md) |
| Spike | scripts/spike.ts |
the Day-4 gate harness (stages aβe) |
| Web | web/ |
Next.js dApp reading live Coston2 state, incl. the /integrations/verify proof route |
Both sides of the market, wallet-connected on Coston2:
| Buy a guard β live FTSO premium | Underwrite β live pool position |
|---|---|
![]() |
![]() |
90 unit tests Β· 100% line / statement / function coverage across all four contracts (branch
coverage 98.7% β the one uncovered branch is a reentrancy-guard revert that Foundry can't credit
through the nested re-entry call; the guard itself is exercised by a dedicated test), plus 4
live-Coston2 fork integration tests (test/ForkCoston2.t.sol) against the
real registry, FtsoV2, and AssetManager. The fork tests skip automatically when no COSTON2_RPC_URL
is set, so offline CI stays green (94 tests with a fork).
forge test # 90 offline Β· 94 with a Coston2 RPC
forge coverage --no-match-coverage "(script|test)" --summaryUnit tests exercise Backstop's own logic with mock Flare contracts; the real integration is proven by the fork tests + the Day-4 spike β never mocked-as-real.
# Contracts
forge soldeer install # deps
forge build && forge test # compile + test
cp .env.example .env # fill PRIVATE_KEY (throwaway testnet key), fund at faucet.flare.network/coston2
# Prove the Flare integration end-to-end on Coston2
npm install && npm run spike:all
# Deploy (Blockscout-verified, no API key)
source .env && forge script script/Deploy.s.sol:Deploy \
--rpc-url "$COSTON2_RPC_URL" --private-key "0x$PRIVATE_KEY" --broadcast \
--verify --verifier blockscout --verifier-url https://coston2-explorer.flare.network/api/
# Run the autonomous keeper
npm run keeper:once # single sweep Β· npm run keeper for the watch loop
# Web app
cd web && npm install && npm run dev # http://localhost:3000- Pool solvency under correlated defaults β many agents failing at once can under-fund the pool; mitigated by a per-agent exposure cap (invariant-tested) and a global solvency cap (total coverage β€ 80% of the pool's live USD value, FTSO-priced), both enforced on-chain β bounded, not eliminated.
- Payout latency = FDC round time β make-whole is fast but bounded by the attestation voting round (~99 s measured); we surface the wait in the UI rather than hide it.
- Linear premium model (
base + kΒ·Ο) β a deliberate MVP simplification, flagged in code.
Everything. Backstop did not exist before this hackathon β no prior codebase, nothing ported,
nothing carried over. First commit
b2fed37
is dated 2026-07-25, inside the program window (development opened June 29, submission closes
August 14). The whole history is public and reviewable:
git log --reverse --format="%h %ad %s" --date=short | head| Before | Built during the program | |
|---|---|---|
| Smart contracts | nothing | 554 lines of Solidity across 4 contracts |
| Flare integration | nothing | 6 engine-class methods (FDC Γ3, FAssets, FTSO v2, Registry) |
| Tests | nothing | 94 tests β 90 unit (100% line/stmt/func coverage) + 4 live-fork, plus 128k-call invariant runs |
| Keeper | nothing | TypeScript/viem autonomous watcher: deadline β RPN request β DA-Layer poll β claim |
| Web app | nothing | Next.js App Router frontend incl. the public /integrations/verify proof route |
| Deployments | nothing | Both contracts deployed and source-verified on Coston2 |
Third-party code is dependencies only (flare-periphery, OpenZeppelin, Foundry, viem/wagmi,
Next.js) β no application logic borrowed.
Milestones, all on-chain: Day-4 FDC gate passed 2026-07-29 (99.3 s round-trip, round 1409442) Β· full end-to-end claim 2026-08-01 (guard #1 PAID, 111.55 C2FLR, block 33493034) Β· contracts hardened and redeployed after clearing all 30 Slither findings.
The economics already shipped β live parameters, readable on-chain from the deployed contract:
| Parameter | Live value | Meaning |
|---|---|---|
baseBips / kBips / sigmaBips |
100 / 50 / 2000 | premium = base + kΒ·Ο = 110 bips = 1.10% of coverage |
agentCapUsd |
$100,000 | max exposure to any single agent vault |
maxUtilizationBips |
8000 | total coverage β€ 80% of live pool USD value |
A desk redeeming $10,000 of FXRP pays $110 to be made whole; the pool holds $1.25 for every $1 of coverage written.
Next, in dependency order:
- Calibrate Ο against real default history. The 20% volatility figure is an honest MVP placeholder β fit it to measured FAssets agent default frequency before pricing real risk.
- External audit of the claim gate and pool share accounting. 94 tests, invariant runs and a clean Slither report are a floor, not a substitute β and a hard prerequisite to mainnet.
- Capped mainnet pilot post-audit: hard pool ceiling, existing caps, prove the loss ratio over a real quarter before lifting anything.
- FBTC / FDOGE coverage β the RPN machinery is asset-agnostic and generalizes to every FAsset.
- Risk-tranched pools (senior / junior) once underwriting demand justifies splitting the curve.
MIT Β© 2026

