Cross-chain intents are eating bridges alive. ERC-7683—co-authored by Uniswap Labs and Across Protocol—standardizes how users express desired outcomes ("swap 1000 USDC on Ethereum for ETH on Arbitrum") instead of hand-crafting multi-step cross-chain transactions. The promise: solvers compete to fill your order, abstracting away bridges, DEX routing, and finality headaches.
The reality: ERC-7683 shifts risk rather than eliminating it. Settlement contracts, solver trust models, and the new orderData signing flow introduce attack surfaces that didn't exist in the bridge era. Here's what auditors and protocol teams need to watch for.
1. Settlement Contract Implementation Bugs
ERC-7683 defines the ISettlementContract interface but leaves implementation entirely to protocol teams. This is intentional flexibility—and intentional risk transfer.
interface ISettlementContract {
function initiate(
CrossChainOrder calldata order,
bytes calldata signature,
bytes calldata fillerData
) external;
function resolve(
CrossChainOrder calldata order,
bytes calldata fillerData
) external view returns (ResolvedCrossChainOrder memory);
}
Every protocol writes its own initiate() and resolve(). Common implementation mistakes include:
-
Missing reentrancy guards on
initiate()when it transfers tokens - Incorrect signature validation that accepts replayed or expired orders
-
Unbounded
fillerDataparsing that can cause out-of-gas or unexpected state changes
Audit checklist:
- Does
initiate()follow checks-effects-interactions? - Are order deadlines enforced on-chain (not just by solvers)?
- Is
fillerDatalength-bounded and safely decoded?
2. The orderData Opacity Problem
The CrossChainOrder struct includes an orderData field typed as bytes. When users sign this via EIP-712, they're signing opaque bytes that their wallet can't meaningfully display:
struct CrossChainOrder {
address settlementContract;
address swapper;
uint256 nonce;
uint32 originChainId;
uint32 initiateDeadline;
uint32 fillDeadline;
bytes orderData; // 👈 opaque to the signer
}
The attack: A malicious frontend crafts orderData that encodes unfavorable terms—extreme slippage tolerance, routing through an attacker-controlled pool, or destination addresses that differ from what the UI displays. The user's wallet shows raw hex for orderData, making verification impossible without protocol-specific tooling.
Mitigation:
- Implement EIP-712
encodeTypeextensions so wallets can renderorderDatafields - Build protocol-specific wallet snap/plugin that decodes and displays order parameters
- Never trust frontend-rendered terms—validate
orderDataagainst on-chain resolution
3. Solver Collusion and Centralized Filler Networks
Intent systems assume competitive solver markets drive fair execution. In practice, many ERC-7683 deployments launch with 3-5 whitelisted fillers. This creates:
- Cartel risk: A small number of fillers can coordinate to offer uniformly worse pricing
- Censorship: Fillers can selectively ignore orders from specific addresses or for specific tokens
- Single point of failure: If the permissioned filler set goes offline, orders expire unfilled
Real-world pattern: Protocol launches with "Phase 1: permissioned fillers" and never reaches Phase 2. The whitelisted filler set becomes a de facto centralized intermediary—the exact thing intents were supposed to eliminate.
What to audit:
- Is there a permissionless fallback path?
- Can the filler whitelist be updated without timelock governance?
- Do fillers post bonds that can be slashed for non-fulfillment?
4. Cross-Chain Timing Exploits
ERC-7683 orders have two critical timestamps: initiateDeadline (when the order must be initiated on the origin chain) and fillDeadline (when it must be filled on the destination chain). The gap between these creates an arbitrage window:
Origin Chain Destination Chain
│ │
├─ Order initiated (t=0) │
│ │
│ ← Finality window (12-60s) → │
│ │
│ ├─ Filler observes order
│ │
│ ├─ Price moves against user
│ │
│ ├─ Filler fills at stale price
│ │
The attack: Fillers can observe price movements during the cross-chain finality window and selectively fill only orders where the price has moved in their favor ("last-look" problem from TradFi, now on-chain).
Mitigation:
- Set tight
fillDeadlinewindows relative to expected finality times - Implement Dutch auction mechanics where filler rewards decay over time
- Use oracle-based pricing with TWAP to prevent point-in-time manipulation
5. msg.sender Identity Confusion at Destination
When a filler calls the destination settlement contract, msg.sender is the filler—not the original swapper. If the destination Message sub-type triggers calls to other contracts, those contracts see the DestinationSettler as the caller:
// Destination contract receives call from DestinationSettler
function onFill(address token, uint256 amount) external {
// msg.sender == DestinationSettler, NOT the original user
// Any access control based on msg.sender breaks here
require(msg.sender == expectedUser, "unauthorized"); // ← always reverts
}
Compounded by EIP-7702: If the swapper has an EIP-7702 delegation active, the identity model becomes even more confusing—the EOA has smart contract capabilities, but the fill is executed by a different entity entirely.
Audit checklist:
- Does the destination flow rely on
msg.senderfor authorization? - Are callback hooks (
onERC721Received,onERC1155Received) handled correctly when the recipient is a delegated EOA? - Is the original swapper address passed and validated through the settlement data?
6. Replay and Nonce Management Across Chains
ERC-7683 orders include a nonce field, but nonce management is left to each settlement contract implementation. Common mistakes:
- Per-chain nonce isolation: A nonce used on Ethereum doesn't invalidate the same order on Arbitrum if the settlement contracts don't share state
-
Missing nonce cancellation: Users can't proactively cancel pending orders if the settlement contract lacks a
cancel()function - Batch replay: If multiple orders share a nonce space, filling one doesn't necessarily invalidate others
// Vulnerable: nonce only checked locally
mapping(address => mapping(uint256 => bool)) public orderFilled;
function initiate(CrossChainOrder calldata order, ...) external {
require(!orderFilled[order.swapper][order.nonce], "already filled");
orderFilled[order.swapper][order.nonce] = true;
// ... but the SAME nonce could be valid on another chain
}
Mitigation:
- Include
originChainIdin the EIP-712 domain separator (ERC-7683 does this, but verify implementations) - Provide explicit
cancel()andbatchCancel()functions - Consider monotonic nonce schemes that invalidate all orders below a threshold
7. Oracle Dependency in Price Verification
Some ERC-7683 settlement contracts use on-chain oracles to verify that fillers provided fair execution. This introduces classic oracle risks into the intent flow:
- Stale oracle prices can make unfair fills appear valid
- Oracle manipulation via flash loans can make manipulated fills pass verification
- Multi-chain oracle desync where prices on origin and destination chains diverge during settlement
The compound risk: Unlike simple swap protocols where oracle manipulation only affects one transaction, in intent systems a manipulated oracle can validate an entire batch of unfair fills across multiple orders.
Audit checklist:
- What oracle does the settlement contract use for price verification?
- Is there a maximum staleness threshold?
- Can the oracle be manipulated within a single transaction (flash loan risk)?
- Is there a dispute mechanism if oracle-verified fills were actually unfair?
Building Secure ERC-7683 Implementations
If you're building on ERC-7683, here's a condensed security framework:
Pre-Deployment
- Formal verification of settlement contract state transitions
- Fuzzing with Foundry invariant tests covering cross-chain message ordering
- Independent audit focused on the seven risk areas above
- Solver simulation testing with adversarial filler behavior
Post-Deployment
- Runtime monitoring via Forta or Hypernative for anomalous fill patterns
- Gradual decentralization of the filler set with slashing for misbehavior
- Circuit breakers that pause settlement if fill-to-oracle price deviation exceeds threshold
- Order flow analysis to detect solver collusion patterns
For Users
-
Verify
orderDatausing protocol-provided tools before signing - Set tight deadlines to minimize cross-chain timing exposure
- Use protocols with permissionless filler sets to avoid centralization risk
- Monitor fill quality against market benchmarks
Conclusion
ERC-7683 is a significant step toward standardizing cross-chain interoperability. But standards don't guarantee security—implementations do. The shift from bridges to intents trades one set of trust assumptions (bridge validators) for another (competitive solver markets). Both can fail.
The seven risk areas outlined here aren't theoretical. As intent-based volume grows in 2026—already surpassing traditional bridge volume on several routes—these attack surfaces will be tested by increasingly sophisticated MEV searchers, phishing operators, and exploit developers.
Audit your settlement contracts like they're the new bridges. Because they are.
This article is part of the DeFi Security Research series. Follow for weekly deep dives into smart contract vulnerabilities, audit techniques, and security best practices.
Tags: #security #blockchain #defi #smartcontracts
Top comments (0)