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:

  1. 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

  2. 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

  1. User creates intent on hub chain

  2. Solver sees intent and locks funds on spoke chain

  3. Spoke chain notifies hub of the fill attempt

  4. Hub validates and settles the trade

  5. Hub notifies spoke to release funds to user

  6. 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 specification

  • Emits: IntentCreated

  • Requirements:

    • inputAmount must be > 0

    • Input tokens must be approved to contract

Cancels an existing intent and returns remaining input tokens.

  • intent: The intent to cancel

  • Emits: IntentCancelled

  • Requirements:

    • 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 fillIntent but creates intent if it doesn't exist

  • Marks intent as pending payment

  • Used for optimistic filling scenarios

Administrative Functions

Registers a spoke chain filler contract.

  • chainID: Chain ID of the spoke

  • spokeAddress: Address of the IntentFiller contract on spoke chain

Manages solver whitelist for cross-chain fills.

  • solver: Address of the solver

  • whitelisted: 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 dstAddress from the original intent

    • Stored 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 recipient

  • Requirements:

    • 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 cancel

  • Requirements:

    • 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

  1. 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:

  2. 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

  1. 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 dstChain must be set to the hub chain ID

  2. 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

  1. Native to ERC20 Intent:

  1. 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

  1. 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.

  2. 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.

  3. 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:

  1. User sends tokens from Chain A to Hub

  2. Solver fills the intent on the Hub Chain

  3. Hub uses AssetManager to bridge directly to Chain B

  4. 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

  1. User must approve the contract for inputAmount + fee

  2. The full amount (including fee) is transferred to the contract

  3. The fee data is stored in the contract's state

During Fill Operations

  1. For full fills:

    • The fee is sent to the fee receiver

    • The remaining amount is sent to the solver

  2. 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

  1. If the intent is cancelled before any fills:

    • The full fee is returned to the creator

  2. 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

  1. Fees are always denominated in the input token

  2. The fee amount must be approved along with the input amount

  3. Fees are handled automatically by the contract

  4. Partial fills result in proportional fee distribution

  5. Cancellation returns any unclaimed fees to the creator

Last updated