Intents & Batching
Paragon Flow upgrades swapping from “send a transaction and hope” to sign an intent, batch with others, settle with best execution, and share the surplus. It’s the engine behind Paragon Shield’s.
TL;DR
You sign an EIP-712 Intent (not a transaction).
A Batcher groups intents for a short window and asks Solvers to propose a settlement.
The best proposal is executed on-chain through FlowSettlement, which:
enforces your bounds (
minOut, deadline, receiver),computes surplus = amountOut − minOut,
splits surplus to Trader / LPs used / stXPGN lockers,
emits auditable events (Proof-of-Best-Execution).
If no solver can beat your bounds, the batch reverts for you (or, if you opted in, falls back to a normal router swap).
Why intents?
MEV resistance: batched clearing + private relay kills most sandwich vectors.
Better pricing: solvers can route multi-hop across multiple venues and cross-match flows.
Programmable refunds: surplus is shared to the right parties automatically.
Key actors
Trader: signs an Intent.
Batcher/Relay: groups intents, broadcasts to whitelisted solvers.
Solver(s): search for best settlement across Paragon pools (+ external DEXes later).
FlowSettlement: on-chain verifier/executor; distributes surplus to vaults.
The Intent (EIP-712)
Preferences bitfield (prefs)
prefs)0..1privacy: 0=Lite, 1=Private, 2=Stealth2fallback: 0=No fallback (revert), 1=Fallback to router if solver fails3cashback mode: 0=claim to wallet, 1=auto-stake to stXPGN4..7reserved
You can cancel any outstanding intent by incrementing your nonce via
FlowSettlement.cancel(nonce)or signing a replacement with a higher nonce.
Batching windows
Window: ~1 block on BNB (testnet setting), adaptive later.
Priority: FIFO within the same gas price band.
Max batch size: capped to keep gas predictable (configurable).
Liveness: if no valid solver submission before window end → optional fallback or revert.
Auction & scoring
Solvers submit a Settlement:
Score = (expectedOut − minOut) − gasCostEquivalent − penalties
expectedOut − minOut → higher is better (more surplus).
gasCostEquivalent → convert gas to output token via oracle.
penalties → for unhealthy routes (too many hops, stale pools, unsafe external venues).
Tie-breakers: fewer hops → earlier timestamp → lower variance in sim.
Batcher picks the top-score, builds a bundle, and sends it to FlowSettlement.execute.
On-chain settlement (Solidity surface)
Settlement checks
signature & domain match
block.timestamp ≤ deadlineuser allowance/transferFrom succeeds for
amountInRouter performs the
routeDataswaps atomicallyamountOut ≥ minOutelse revert (or fallback if allowed)
Surplus & payouts
Surplus:
surplus = amountOut − minOut(0 if negative).Splits (default):
60% → Trader (instant claim or auto-stake to stXPGN)
30% → LPRebateVault (credited to pairs actually touched by the route)
10% → LockerVault (stXPGN / veFlow lockers)
Protocol can take a small cut (0–5%) of surplus before splits (DAO-governed).
LPRebateVault accounting
We snapshot pair, blockNumber, usedLiquidity for the settlement.
LPs claim proportionally to the liquidity they had in that block.
External venues (phased)
Phase 0 (testnet): Paragon pools only.
Phase 1: add whitelisted Pancake/Thena routes with per-venue caps and slashing bonds for executors.
Phase 2: open allow-list, higher caps, cross-DEX batch netting.
Fallbacks & failures
Revert (default) if no solver produces
amountOut ≥ minOut.Fallback to Router if the
prefsbit is set. UI shows: “Shield unavailable, executed via Router.”Partial batch failure: single intent revert doesn’t affect others; we isolate by executing intents independently (no shared state assumptions).
Security model
Permissions: FlowSettlement is upgrade-gated by timelock + multisig.
Solver bonds: executors post bonds and can be slashed (mis-pricing, invalid routing, griefing).
Replay protection: per-user nonces + domain separation.
Oracle usage: only for gas costing and sanity checks; user bound (
minOut) is the real guard.Emergency: Shield can be paused without affecting classic swaps.
Relay API (testnet draft)
Submit intent
Status
WebSocket feed
wss://.../v1/stream → ShieldSubmitted / ShieldSettled notifications.
Frontend integration (quick guide)
Prepare intent & sign
POST to relay (or call
executedirectly if you run a solver).Show live status (pending → settled).
If settled, extract surplus + rebate amounts from event or status and surface “You saved X%”.
Claims
Trader: call
TraderRebateVault.claim(user)if not auto-staked.LPs: show accrued Flow earnings on the pool page (per-block snapshots).
Testnet parameters (current)
Chain: BNB Testnet
Batch window: ~1 block (adaptive 1–2 blocks if congestion)
Min trade size: none (UI may nudge > $5)
Max hops: 4 (Paragon pools only)
Surplus split: 60/30/10 (TBD via DAO for mainnet)
Contracts:
FlowSettlement:FLOW_SETTLEMENT_ADDRESSTraderRebateVault:TRADER_REBATE_VAULTLPRebateVault:LP_REBATE_VAULTLockerVault:LOCKER_VAULT
Developer FAQs
Q: Can I cancel/replace an intent?
Yes. Call cancel(newNonce) or sign a newer intent with a higher nonce.
Q: Does batching increase gas? Settlement for a batch is similar to one swap with comparable hops. Slightly higher overhead is typically offset by better price (surplus).
Q: How are LP rebates mapped to pairs?
Solvers must provide lpTouchSet per hop; settlement verifies via router events and credits the vault.
Q: Can I force a public (non-Shield) swap?
Yes—use classic Router or set prefs.fallback=true and toggle Shield off in the UI.
Roadmap hooks
Limit/RFQ intents
Time-weighted auctions for large orders
Cross-DEX netting (match internal flows to reduce market impact)
veFlow voting to steer surplus weights and utilization emissions
Last updated