Skip to main content

Overview

Understanding DEX Transaction Complexity

When a user executes a swap on Ethereum, the transaction often involves multiple layers of intermediaries before reaching the actual liquidity pools. A user might interact with a wallet like Rabby, which routes through LiFi, which in turn uses 1inch, which finally pulls liquidity from Uniswap and Curve pools. Each layer serves a purpose—optimizing routes, aggregating liquidity, or providing user-friendly interfaces. However, this complexity makes it challenging to understand who facilitated the trade and where the actual liquidity came from. This model aims to create a generalized swap flow model to map the flow of a swap execution from its origin through intermediary routing systems like meta-aggregators, aggregators, or solvers, to the decentralized exchanges’ liquidity pools and vaults that settle it. This model helps users understand and explore the flow of DEX transactions through frontends and intermediaries.
  • Where trades originate (e.g., wallets, dApps, bot contracts, interfaces)
  • How they are routed (via aggregators, meta-aggregators, or intent-based systems)
  • Where liquidity is sourced (DEX protocols and pools that ultimately settle the swap)

Models

There are currently 2 versions of the orderflow model. Models with the “unhydrated” prefix are models without frontend/intermediary labels. The v2 (New) orderflow model is currently only supported on Ethereum, Unichain, Arbitrum, and Base.
ModelsVersionDescription
dex.orderflow_liquidity_viewNewProvides a flattened view of liquidity sources, detailing project, protocol, and pool address for each transaction.
dex.unhydrated_orderflow_v2NewAggregates data from dex.trades and dex.aggregator_trades and includes additional fields for meta-aggregators, aggregators, solvers, and PMMs involved in the transaction.
dex.orderflowLegacySame data as dex.unhydrated_orderflow model, with the frontend labeled.
dex.unhydrated_orderflowLegacyProvides an aggregated view of swap events from dex.trades and dex.aggregator_trades at the transaction level. Does not include meta-aggregators, aggregators, solvers, or PMMs.
Model: dex.orderflow_liquidity_view (New)The dex.orderflow_liquidity_view model is a flattend view of the dex.unhydrated_orderflow/_v2 model, where all the relevant swap details are compressed within a unit of transaction hash. The entiites (frontend, meta-aggregator, aggregator, solver, pmm) labels are normalized to their respective project names.In this mode, a swap that originates from 1 frontend and is routed to 3 liquidity sources will be represented as 3 rows in the model.
ColumnDescription
frontendThe originating interface or application through which the user initiated the trade (e.g., MetaMask, Lifi, 1inch).
meta_aggregatorThe higher-level routing system that connects multiple aggregators or intent-based systems (e.g., Lifi, Bungee).
aggregatorThe protocol responsible for routing swaps across DEXs to optimize execution (e.g., 1inch, Paraswap, Kyberswap).
solverThe intent solver or filler responsible for executing the trade on behalf of a user in intent-based systems (e.g., CoW Protocol solver, Uniswap X filler).
solver_addressThe on-chain address of the solver or filler that executed the swap.
pmmThe private market maker (PMM) if the trade involved a off-chain liquidity provider (e.g., Tokenlon, 0x RFQ).
pmm_addressThe on-chain address of the private market maker (PMM).
liquidityThe name or identifier of the liquidity source (DEX or pool) involved in the trade. For Uniswap project, the liquidity identifier is resolved to the corresponding version of the pool (e.g., Uniswap V3, Uniswap V4).
liquidity_indexThe position or ordering index of the liquidity source within the transaction, if multiple pools are used.
liquidity_pool_addressThe contract address of the liquidity pool that facilitated the trade.
pairThe token pair exchanged in the liquidity pool (e.g., WETH-USDC).
projectThe DEX or protocol project associated with the liquidity source (e.g., Uniswap, Velodrome, Balancer).
protocolThe specific protocol version or sub-implementation of the project (e.g., Uniswap V3, Curve StableSwap, Velodrome V2).
usd_amountThe USD value of the trade attributed to this liquidity pool.
v4_idThe unique Uniswap V4 hook identifier (if applicable), used for attributing swaps to specific hook contracts.
swap_max_usd_amountThe maximum USD volume among all swap events within the transaction. By proxy, we can take this as the USD volume of the transaction.
swap_total_usd_amountThe total USD volume summed across all swaps in the transaction, both executed by pools (in dex.trades) and routed through intermediaries (in dex.aggregator_trades).
liquidity_detailsA structured JSON field containing detailed pool-level trade data (project, protocol, pair, pool address, USD volume, and log index). For v4 Uniswap, the pool id is also included.
transaction_hashThe unique identifier (hash) of the transaction on-chain.
transaction_indexThe index of the transaction within the block.
block_timestampThe timestamp when the block containing the transaction was confirmed.
block_numberThe block height in which the transaction was included.
swapper_addressThe address of the end user or contract that initiated the swap.
from_addressThe originating address from which the transaction was sent.
to_addressThe recipient or target contract address to which the transaction was directed.
_created_atThe timestamp when this record was first created in the dataset.
_updated_atThe timestamp when this record was last updated or refreshed.
Model: dex.orderflow (Legacy)
Column NameDescription
frontendThe frontend interface used for the transaction
block_numberThe block number in which the transaction was included
block_timestampThe timestamp of the block in which the transaction was included
transaction_hashThe hash of the transaction
transaction_indexThe index of the transaction within the block
swapper_addressThe address of the user performing the swap. For most trades, this comes from the transaction_from_address field in dex.trades / dex.aggregator_trades. However, for UniswapX and CowProtocol swaps, it comes from the sender field instead.
from_addressThe address initiating the transaction (msg.sender)
to_addressThe address receiving the transaction
is_aggregatorFlag indicating if the transaction is an aggregator
usd_volumeThe max usd_amount of the swap within the entire transaction
total_usd_volumeThe sum of the usd_amount of all swaps within the transaction
sendersArray of addresses sending tokens in the transaction
recipientsArray of addresses receiving tokens in the transaction
tokens_soldArray of tokens sold in the transaction
integratorsArray of integrator names involved in the transaction
integrator_tagsArray of integrator contract addresses
aggregator_sourceSource of the aggregator
aggregator_usd_volumeUSD volume of the aggregator portion
aggregatorsArray of aggregator contracts involved
aggregators_countCount of aggregators involved
aggregator_detailsJSON details of aggregator swaps
liquidity_sourceArray of liquidity sources used
liquidity_usd_volumeUSD volume from liquidity sources
liquidity_poolsArray of liquidity pool addresses used
liquidity_pools_countCount of liquidity pools involved
liquidity_detailsJSON details of liquidity pool swaps
total_tradesTotal number of trades in the transaction
unique_idUnique identifier for the transaction

Methodology

Two core abstractions are used to construct the orderflow schemas: dex.trades and dex.aggregator_trades (Table 2). Table 2: Core abstractions used to construct the orderflow schemas
ModelsWhat it RepresentsLiquidity SourceTypical Examples
dex.tradesCaptures AMM swaps emitted directly by liquidity pools, reflecting raw on-chain execution.AMM pools (e.g., Uniswap v2/v3, Curve, Balancer), PMMs, CoWs (if directly settled)User swaps on Uniswap v3 pool 0x…, Curve pool 0x…
dex.aggregator_tradesRepresents swaps routed through intermediaries such as aggregators, intent-based protocols, or RFQ systems (e.g., Odos, 1inch, CoW Protocol solvers). These swaps source liquidity from AMMs, PMMs, or solver networks.Aggregators/routers (e.g., 1inch, Odos, Velodrome Router) which tap into liquidity from AMMs, RFQs, or CoWs. RFQ, CoW, and intent-based swaps are included in this model.User swaps on Odos → Odos routes into Uniswap v3 and Curve

The Core Challenge: Attribution in Multi-Layered Transactions

Consider a typical complex swap: A user connects their MetaMask wallet to Jumper Exchange (LiFi’s frontend), which routes through KyberSwap Aggregator, ultimately pulling liquidity from two Uniswap V3 pools and one Curve pool. This single transaction generates multiple swap events across different protocol layers. The fundamental question becomes: How do we attribute this transaction? We sought to identify the following entities involved in a swap:
EntityDefinition / RoleExamples
FrontendUser-facing interface that collects swap intent and submits transactions.Uniswap UI, MetaMask Swaps, Rainbow Wallet
Meta-AggregatorRoutes swaps across multiple aggregators to find the best execution path. Intent-based protocols are currently grouped as meta-aggregators.CoWSwap, LiFi, KyberSwap
AggregatorOptimizes trade execution across multiple DEX pools and liquidity sources.1inch, OpenOcean, Matcha
Liquidity SourcePools or venues providing actual token liquidity for swaps.Uniswap v2/v3, Curve, Balancer, Kyber AMM
Private Market Maker (PMM)Off-chain liquidity providers offering RFQ prices and competitive execution for large trades.Wintermute, Flowdesk
SolversAgents that determine optimal execution across DEXs, PMMs, and liquidity pools; can batch or net trades.CoW Protocol solvers, UniswapX fillers

Stage 1: Categorizing DEX Protocols

We classify all DEX protocols into different tiers based on their role in the execution mechanism. This classification reflects both the technical complexity of each protocol type and its position in the execution stack. Every swap event, whether from a high-level aggregator or a direct pool interaction, is tagged with its protocol category and assigned the corresponding priority ranking. Table 3: Protocol Classification Hierarchy
Priority RankProtocol CategoryOrderflow EntityExamplesCore FunctionData Source
1Intent-Based ProtocolsMeta-AggregatorsCoW Protocol, Uniswap X, 0x SettlerBatch auctions and solver competitions that optimize executiondex.aggregator_trades
2Meta-AggregatorsMeta-AggregatorsBungee, LiFi, Kyber Aggregator v2Orchestrate multiple aggregators for cross-chain or complex routesdex.aggregator_trades
3Standard Aggregators & RFQsAggregators1inch AR, 1inch LOP, Paraswap, OpenOceanRoute trades across multiple liquidity sourcesdex.aggregator_trades
4AMM / Vaults SwapsLiquidity SourcesUniswap, Curve, Balancer, Fluid, AerodromeThe actual liquidity pools where tokens are exchangeddex.trades
Priority Rationale:
  • Intent-based protocols (rank 1) receive the highest priority because of their fundamentally different execution model. Instead of deterministic routing, they rely on solvers or batch auctions.
  • Meta-aggregators (rank 2) are distinguished from standard aggregators because they make routing decisions across multiple aggregation layers.
  • Standard aggregators (rank 3) represent the conventional routing layer, whether through traditional aggregation algorithms or request-for-quote systems where professional market makers provide liquidity.
  • Direct AMM pool or vault swaps (rank 4) represent the liquidity sources of most DEX swaps, where the underlying tokens are exchanged.
We assign each swap event’s project name (e.g., CoW Protocol) to the corresponding orderflow entity (e.g., Meta-Aggregator). Since CoW Protocol is not considered an aggregator or liquidity source in this context, those fields are set as null.

Stage 2: Labeling Transaction Origin

Most transactions don’t explicitly encode which wallet or frontend the user employed. We rely on a mix of transaction-level contract interactions and decoded event log data to infer the origin. Several aggregators emit clues about the transaction origin in their event logs. These can be either string text stating the integrator of the DEX aggregator, or addresses pointing to the referral or affiliate address of the swap. For example, KyberSwap’s ClientData events, LiFi’s integrator tags, and Paraswap’s partner addresses are identifiers that tell us whether the user came from MetaMask, Rabby, Ledger, or another interface. Table 4: Transaction Origin Attribution
Priority RankProtocol CategoryData SourceOrigin Logic
1Intent-Based Protocolsdex.aggregator_tradesThe project name is assigned as the origin if the transaction-level to_address is the contract address emitting the swap event.
2Meta-Aggregatorsdex.aggregator_tradesWe label the origin as the integrator if populated. Integrator fields for the following protocols are populated based on event logs:
- KyberAggregator v2: source field in decoded ClientData event
- LiFi: integrator field emitted in swap event
- Bungee Protocol: routeName field is a hex string that can be mapped to integrators
3Standard Aggregators & RFQsdex.aggregator_tradesWe label the origin as the integrator if populated. Integrator fields for the following protocols are populated based on event logs:
- 0x: Affiliate Address or Fee Recipient Address mapping to integrators
- OpenOceanV2: referrer address mapping to integrators
- Paraswap: partner address mapping to integrators
- OdosV2: referralCode address mapping to integrators
4AMM / Vaults Swapsdex.tradesWe leave the origin data for these swaps as null. If no aggregators with integrator data are present, we rely on labeling the contract address interaction to infer the transaction origin.

Stage 3: Transaction-Level Aggregation and Conflict Resolution

Once each swap event is categorized and labeled with origin information, we aggregate all events at the transaction level using transaction_hash as the key. This consolidation produces a single orderflow record per transaction, but it requires resolving conflicts when multiple protocols of different types participate.

Selection Logic: Priority-Based with Chronological Tiebreaking

When multiple protocols appear in a single transaction under each entity (e.g., meta-aggregator), we apply a two-tier selection rule:
  1. Primary criterion: Priority ranking (lowest rank number = highest priority)
  2. Secondary criterion: Event order (lowest log_index = first event)
This handles two scenarios: Scenario A: Different Protocol Types When protocols from different tiers participate—for example, CoW Swap (rank 1) and KyberSwap Aggregator (rank 2)—the protocol with higher priority wins. CoW Swap is selected as the meta_aggregator. Scenario B: Same Protocol Type When multiple protocols share the same priority—for example, both LiFi and Bungee (both rank 2) routing portions of the same trade—the chronological tiebreaker applies. The protocol whose event appears first (lowest log_index) is selected.

Stage 4: Final Schema Mapping

The aggregation process produces a transaction-level orderflow record with the following attribution dimensions:
Field NameData TypePopulated ByDescription
originvarcharWhenever integrators are present. If not, populated by labeling transaction_to_address from Allium’s label.The frontend or entry point of the transaction.
integratorsvariant (array)Aggregators with event metadata.Normalized frontend/wallet identifiers (e.g., 'ledger', 'exodus', 'jumper_exchange') extracted from KyberSwap ClientData, LiFi tags, Paraswap partner fields
meta_aggregatorvarcharIntent-based (rank 1) or meta-aggregators (rank 2)Project name of highest-priority meta-aggregator or intent protocol (e.g., 'lifi', 'cow_protocol')
aggregatorvarcharStandard aggregators (rank 3) when no rank 1-2 presentProject name of standard aggregator (e.g., 'paraswap_v5', '1inch'). NULL if meta-aggregator exists
liquidity_detailsvariant (array)All AMM swaps from dex.tradesArray of pool objects with project, protocol, liquidity_pool_address, pair, usd_amount, log_index, id (V4 hooks). Excludes RFQ fills
solver_addressvarcharIntent-based protocols onlySolver/filler address: CoW = transaction_from_address, Uniswap X = filler field, 0x Settler = contract_address
pmm_addressvarcharRFQ and limit order protocolsPrivate market maker address from maker, executor, or signerWallet fields (1inch LOP/AR, Paraswap RFQ, Tokenlon, AirSwap)
swapper_addressvarchar(42)All transactionsFor intent-based swaps: sender_address, others use transaction_from_address
from_addressvarchar(42)All transactionsTransaction sender (transaction_from_address)
to_addressvarchar(42)All transactionsTransaction recipient (transaction_to_address)
usd_volumefloatAll transactionsLargest single swap leg, approximates user’s trade size
total_usd_volumefloatAll transactionsSum of all swap volumes including intermediate hops
user_token_inputvarcharAll transactionsFirst token sold in chronological order
user_token_outputvarcharAll transactionsLast token bought in chronological order
block_numberbigintAll transactionsBlock number of the swap execution
block_timestamptimestamp_ntz(9)All transactionsBlock timestamp of the swap execution
transaction_indexbigintAll transactionsTransaction position in block
transaction_hashvarchar(66)All transactionsUnique transaction identifier
_created_attimestamp_ntz(9)All transactionsRecord creation timestamp
_updated_attimestamp_ntz(9)All transactionsRecord update timestamp

Liquidity View Flattening

To enable granular analysis of liquidity routing patterns, the dex.orderflow_liquidity_view flattens the transaction-level schema into a liquidity-source-level schema. This transformation creates one row per liquidity source. If a swap splits into 4 different AMM pools, it will be represented as 4 rows in the liquidity view model. This allows users to plot the output in a Sankey chart and also enables queries like:
  • “Which AMM pools does LiFi route through most frequently?”
  • “What percentage of CoW Protocol swaps use Uniswap V3 vs V4?”
  • “Which solvers access which PMMs?”

Flattened Schema Structure

The view maintains all transaction-level attribution fields (origin, meta_aggregator, aggregator, solver, etc.) and adds per-liquidity-source columns:
Field NameData TypeSourceDescription
liquidityvarcharliquidity_detail['project'] or ['protocol']Normalized liquidity source name (e.g., ‘Uniswap V3’, ‘Curve’)
liquidity_indexbigintArray positionSequential order in which liquidity source was accessed (0 = first)
liquidity_pool_addressvarchar(42)liquidity_detail['liquidity_pool_address']Pool contract address for AMM trades
pairvarcharliquidity_detail['pair']Trading pair identifier (e.g., ‘WETH-USDC’)
projectvarcharliquidity_detail['project']Raw project name (e.g., ‘uniswap’, ‘curve_v1’)
protocolvarcharliquidity_detail['protocol']Protocol version (e.g., ‘uniswap_v3’, ‘uniswap_v4’)
usd_amountfloatliquidity_detail['usd_amount']USD volume routed through this specific liquidity source
v4_idvarcharliquidity_detail['id']Uniswap V4 / Eulerswap V1 hook identifier (pool ID with hooks)

Data Labels

We source the labels of solvers, frontends, private market makers, and hooks from various publicly available sources. Frontend labels are identified by a mix of integrators used by DEX aggregators. The table below outlines the labeling heuristics for the intermediaries involved in the swap.
IntermediariesLabeling HeuristicsLabel Source
OriginFor intent-based protocols, we attribute the swap frontend to the DEX project: cow_protocol, uniswap_x, zeroex_settler if the contract address is also the to_address of the swap.

For aggregator protocols with integrator data, we will label them and attribute them as the frontend: zeroex_api, lifi, kyberswap_aggregator_v2, zeroex_v4, paraswap_v5, openocean_v2.

For aggregated orderflow without any labels, we will rely on labeling the contract interaction as the frontend (i.e., labeling the transaction_from_address).
Allium maintains a repository of DEX aggregators and routers from publicly available sources such as block explorers, public GitHub repositories, and project documents.

This list is periodically updated by our attribution team as we identify unlabeled contracts generating large volumes.
Private Market Makers & SolversSourced from publicly external sources. PMMs and solvers are identified by their addresses.Seeded from Flashbots’s Maker List.

Additionally, we source unlabeled PMMs & solvers from publicly available sources.
Liquidity SourceBased on the underlying DEX project where the swap receives its liquidity.

For Uniswap project, this is reflected as Uniswap V2, V3, and V4 based on the protocol version.
From project field of dex.trades
UniswapV4 HookWe identify the hook ID of the swap event and the corresponding hook contract that it is associated with.Provided by Uniswap Foundation and maintained by the UF team from this Dune query.

Design Assumptions and Limitations

The liquidity flow schema was designed to generalize how swap executions move through the DeFi stack, beginning at user-facing interfaces, passing through intermediaries such as aggregators and solvers, and concluding in settlement across DEX liquidity pools. In creating a standardized model, we have made certain simplifications and assumptions, leading to inherent trade-offs in attribution. DeFi infrastructure evolves constantly. New aggregators launch, existing ones add features, and protocols migrate to new contract versions. The schema requires active curation to stay accurate:
  • Contract registries must be updated as protocols deploy new routers
  • Event decoding must expand to parse new integrator metadata formats
  • Classification rules need periodic review as protocol boundaries shift
In short, this work is inherently ongoing: the schema is not static and must adapt to reflect the evolving DEX landscape. Maintaining the accuracy and interpretability of the schema involves continuously identifying new protocols, routers, and integrators. This involves updating contract labels, decoding new events, and re-evaluating intermediary hierarchies to ensure analytical consistency over time.

Known Gaps

There are known gaps in the coverage of aggregators and DEXs. Frontend and volume coverage of protocols not indexed by Allium will not be reflected in the orderflow schema. The following projects/protocols have been added to our roadmap for support.
ProjectsCategoryAdditional Notes
Bebop AggregatorAggregatorPlanned support by Q1 2026
LiquidMeshAggregatorPlanned support by Q1 2026
MetaMaskAggregator*Not currently indexed, as we use contract interaction to infer this. Planned support by Q1 2026
Angstrom V4 IntegratorSwapsPlanned support by Q1 2026