Intents
Overview
The Intents system is a cross-chain trading infrastructure that enables users to express their trading desires ("intents") on a central hub chain while allowing solvers to fulfill these intents from any supported spoke chain. The system consists of two main contracts:
Intents Contract (Hub) - The central coordinator that:
Manages intent creation and lifecycle
Handles settlement of trades
Coordinates cross-chain communication
Maintains the source of truth for all intents
IntentFiller Contract (Spokes) - Deployed on spoke chains to:
Enable local fulfillment of intents
Lock solver funds during cross-chain settlement
Relay fill confirmations back to the hub
Core Architecture
Centralized Settlement
All intent logic and final settlement occurs on the hub chain. This design choice provides several benefits:
Single source of truth for intent status
Simplified accounting and settlement
Reduced cross-chain complexity
Atomic execution of trades
Spoke Chain Role
Spoke chains serve as execution venues that:
Allow solvers to fill intents directly on destination chains
Provide faster user experience by avoiding cross-chain delays
Act as temporary fund escrow for cross-chain settlements
Do not maintain any intent state - they only facilitate fills
Flow Example
User creates intent on hub chain
Solver sees intent and locks funds on spoke chain
Spoke chain notifies hub of the fill attempt
Hub validates and settles the trade
Hub notifies spoke to release funds to user
Solver receives payment on hub chain
This architecture ensures that while execution can happen anywhere, settlement and intent state management remain centralized on the hub chain, simplifying the system while maintaining security and atomicity.
Intents System - Data Structures and Events
Intent Structure
The core Intent structure represents a user's trading desire with the following fields:
Events
Intent Lifecycle Events
Supporting Structures
IntentState
Tracks the current state of an intent:
PendingIntentState
Tracks cross-chain fills in progress:
ExternalFill
Records details of cross-chain fills:
Payout
Tracks pending payments to solvers:
Intents System - Function Interface
Hub Chain (Intents Contract)
Intent Management
Creates a new intent and transfers input tokens from the creator.
intent: The complete intent specificationEmits:
IntentCreatedRequirements:
inputAmountmust be > 0Input tokens must be approved to contract
Cancels an existing intent and returns remaining input tokens.
intent: The intent to cancelEmits:
IntentCancelledRequirements:
Intent must exist
Caller must be creator OR deadline must have passed
No pending fills can exist
Fill Operations
Fills an intent either partially or fully.
intent: The intent to fill_inputAmount: Amount of input tokens to consume_outputAmount: Amount of output tokens to provide_externalFillId: ID for cross-chain fills (0 for hub-chain)Requirements:
Intent must exist and not be pending payment
Fill amount must be valid
Output amount must meet minimum requirements
Solver restrictions must be met
Pre-fills an intent before input tokens are received.
Similar to
fillIntentbut creates intent if it doesn't existMarks intent as pending payment
Used for optimistic filling scenarios
Administrative Functions
Registers a spoke chain filler contract.
chainID: Chain ID of the spokespokeAddress: Address of the IntentFiller contract on spoke chain
Manages solver whitelist for cross-chain fills.
solver: Address of the solverwhitelisted: Whether solver is approved
Spoke Chain (IntentFiller Contract)
This section will be implemented by the spoke chain and thus wont be exactly the same as the EVM implementation.
Fill Data Structure
The Fill struct is the core data structure used to represent fill attempts on spoke chains:
Field Details:
fillID:Unique identifier generated by the solver
Used to track the fill across chains
Must be unique per intent-solver combination
Used to prevent double-fills
intentHash:The keccak256 hash of the original intent from the hub
Stored in bytes format for cross-chain compatibility
Used to link the fill to the original intent
solver:Address of the solving entity in bytes format
Will receive payment on the hub chain upon successful fill
Cross-chain format allows for different address formats across chains
receiver:Destination address for the filled tokens
Matches the
dstAddressfrom the original intentStored in bytes for cross-chain compatibility
token:Address of the token being transferred
Stored in bytes format for cross-chain compatibility
Can be the zero address (represented in bytes) for native currency
amount:Quantity of tokens being transferred
Fill Operations
Creates a new fill on spoke chain.
fill: Fill details including amount and recipientRequirements:
For native token, msg.value must match fill amount
For ERC20, tokens must be transferred to contract
Cancels a pending fill and returns tokens.
fill: Fill to cancelRequirements:
Fill must exist
Caller must be original filler
Token Management and Cross-Chain Asset Handling
Native Token Support
The Intents system supports native tokens (ETH) as both input and output tokens. Native tokens are represented by the zero address (address(0)) in the system.
Native Token Usage
As Input Token:
When creating an intent with native token as input, the user must send the correct amount of ETH with the transaction
The amount must include both the input amount and any fees
Example:
As Output Token:
When filling an intent with native token as output, the solver must send the correct amount of ETH with the transaction
The native token can only be sent to the hub chain (no cross-chain native token transfers)
Example:
Native Token Restrictions
Cross-Chain Limitations:
Native tokens can only be used on the hub chain
Cross-chain transfers of native tokens are not supported
When using native tokens, the
dstChainmust be set to the hub chain ID
Fee Handling:
Fees in native tokens work the same way as ERC20 tokens
The total amount sent must include both the input amount and the fee
Fees are distributed proportionally for partial fills
Examples
Native to ERC20 Intent:
ERC20 to Native Intent:
Token Mapping System
The system uses the AssetManager contract to maintain mappings between tokens across different chains. Each token has:
A home chain (where it originates)
A address on each chain where it exists
A relationship with the hub chain representation
Token Transfer Logic
The hub's sendToken function handles all token transfers when filling an intent based on destination chain configuration:
Transfer Cases
To Hub Chain (dstChainID == HUB_CHAIN_ID): When the dst in the intent is set to the hub chain, the token is transferred directly to the user.
To Non-Home Chain (dstChainID != chainID): If the intent is done to a different chain than the token's home chain, the token is transferred to a wallet abstraction on the hub chain for that specific user.
To Home Chain (dstChainID == chainID): If the intent is done to the token's home chain, the token is transferred directly to the user via the AssetManager.
Token Flow Example
For a cross-chain intent where:
Input token is native to Chain A
Output token is native to Chain B
Intent is created and settled on Hub Chain
The flow would be:
User sends tokens from Chain A to Hub
Solver fills the intent on the Hub Chain
Hub uses AssetManager to bridge directly to Chain B
Solver receives payment on Hub chain
External Fill token mappings
While all intents created needs to be between tokens represented on the hub chain, when filling externally the solver must fill the correct token representation on the spoke chain. Which can be queried from the asset manager.
Fee System
Overview
The Intents system supports a flexible fee mechanism that allows for partner fees to be collected during intent execution. Fees are specified in the intent's data field and are handled automatically during the fill process.
Fee Data Structure
Fees are encoded in the intent's data field using the following structure:
Fee Encoding
Fees are encoded in the intent's data field with a type identifier:
Fee Collection Process
During Intent Creation
User must approve the contract for
inputAmount + feeThe full amount (including fee) is transferred to the contract
The fee data is stored in the contract's state
During Fill Operations
For full fills:
The fee is sent to the fee receiver
The remaining amount is sent to the solver
For partial fills:
The fee is proportionally split
The filled portion's fee is sent to the fee receiver
The remaining fee is returned to the creator upon cancellation
During Cancellation
If the intent is cancelled before any fills:
The full fee is returned to the creator
If the intent is partially filled:
The filled portion's fee is sent to the fee receiver
The remaining fee is returned to the creator
Fee Examples
Full Fill
Partial Fill (50%)
Cancellation
Important Considerations
Fees are always denominated in the input token
The fee amount must be approved along with the input amount
Fees are handled automatically by the contract
Partial fills result in proportional fee distribution
Cancellation returns any unclaimed fees to the creator
Last updated