Let's break down the high-level architecture of a batch auction.
CoW Protocol Batch Auctions: How Orderbook, Autopilot, and Solvers Ensure Fair Trading
Batch auctions are a key mechanism of the CoW Protocol that ensures fair pricing and protection against MEV. Unlike traditional DEXs, where each trade is processed individually, the CoW Protocol groups multiple user intentions into batches and runs an auction among solvers for the right to execute them.
These three main components are required for the auction to function.
Order book is an off-chain component with a database, whose API is used to place, cancel, and fetch active orders. It enables interaction between traders, the UI, and other interfaces with the CoW Protocol.
Autopilot is an off-chain service that receives orders from the order book and organizes the auction. It sends auction information to all solvers, collects their quotes, and selects the best one to execute the tasks. If a solver behaves dishonestly, for example by inflating a quote, the system can penalize them through the DAO.
Solver are independent protocol participants who compete for the right to execute a batch of orders. Each solver analyzes the batch of intentions received from Autopilot, looks for optimal execution paths, and submits a quote to Autopilot.
To understand better, let's take a closer look at each participant in the system.
Orderbook
Essentially, it's an off-chain CRUD state service that consists of an API and a database. You can check out the code here.
The Orderbook is the main entry point to the protocol. Through its API, users, UIs, and other integrations can:
- Get quotes for orders (
post/quote) - Place orders (
post/orders) - Cancel orders (
delete/orders) - Retrieve information about the current settled auction
- Track the status of their orders
The full list of API.
You can see the interaction scheme of the orderBook below:
It can be broken down into 3 stages: getting a quote, placing an order, and processing & monitoring the order.
Getting a Quote
User → Order book: POST /quoteThe user sends a quote request with the trade parameters to understand how many tokens they will receive in the swap.Order book → Solver1/SolverN: quote?The Orderbook queries solvers to solve abatchwith a single order, and the solvers return their proposals.Order book → Order book: simulate & pick best resultThe Orderbook simulates the quotes and selects the best one that maximizes the output for the trader, then saves it in the database.Order book → User: quoteReturns the quote to the trader for signing.
Placing an Order
User → Order book: sign & POST /orderThe user signs the order off-chain and sends it to the Order book to be included in the next batch.Order book → Order book: verify order & fetch quoteThe Order book validates the order (format, balances, signature, appData) and looks for a matching quote for classification. If no quote is found, a new one is created.Order book → Database → User: insert order & return UIDThe Order book saves the validated order in the database for the autopilot and returns a unique identifier to the user.
Order Processing and Monitoring
User → User: wait for happy mooThe user waits for the order to be executed. Now it's up to the autopilot and solvers to distribute and execute the order ("happy moo" = successful execution CoW-style).User → Order book: GET /tradesAfter execution, the user requests information about the completed trade.Order book → Database → User: lookup & return tradesThe Order book looks up the order information in the database and returns the details of the completed trade and the results of the solver competition to the user.
Autopilot
You can check out the code of the off-chain service here
When New Auctions Are Created
Autopilot runs continuously and starts a new auction in three cases. First — when users create, cancel, or update their orders. Second — when a new block appears on the blockchain and the network state might change. Third — if more than 2 seconds have passed since the last block and the system decides to check for updates.
This logic helps avoid creating empty auctions without any changes. Solvers have 15 seconds for each auction.
After a winner is selected, the solver has a limited time to send the transaction to the network. If the solver fails to send the transaction within this time, the orders are returned to the next auction.
Detailed Diagram of Autopilot Workflow
The workflow can be divided into 3 stages: data collection, auction formation, solver competition and execution.
Collecting Order Data
Autopilot → Database & Blockchain: Get order informationAutopilot requests information from the shared database with the Orderbook (UIDs, off-chain signatures, owners) and monitors the blockchain:- Pre-signatures: tracks
PreSignatureevents when users sign orders on-chain using thesetPreSignaturefunction - Order cancellations: monitors
OrderInvalidatedevents triggered by theinvalidateOrderfunction - ETH flow: tracks events from the ETH Flow contract — when users create new orders using the network’s native token.
- Pre-signatures: tracks
Autopilot → Autopilot: Cut auctionAutopilot forms an auction batch from all tradable orders. Then, the service fetches token prices in ETH from multiple sources (solvers, Paraswap, 1inch, Uniswap pools). These prices are included in the auction batch so that solvers have a unified view of token prices and to simplify conversion intoscoresusing consistent ETH-based pricing. If a token’s ETH price cannot be fetched, the order is excluded. Essentially, this acts as a price oracle for all solvers.Then it filters out orders that can’t be executed: expired ones, orders with insufficient balance for fill-or-kill, without approval for the contract used for trading, with unsupported tokens, or with invalid ERC-1271 signatures.
Solver Competition
Autopilot → Solver1/2/3: /solveAutopilot sends the auction batch to all registered solvers. Solvers have a limited time (15 seconds by default, configurable viasolve_deadlinein the Autopilot config) to analyze the auction and return a solution. This time limit helps maintain fast auction cycles.Solver1/2/3 → Autopilot: Proposed batchSolvers analyze the auction and return their proposals with calculatedscores, which represent the quality of the solution.Autopilot → Autopilot: Pick winnerWhen selecting a winner, Autopilot performs additional checks and filters the solutions to ensure fairness. For more details on this filtering system, see the section "Score Calculation and Winner Selection Algorithm."
Execution and Finalization
Autopilot → Winner: /settleAutopilot notifies the winner to execute the solution. The solver is responsible for submitting the transaction on-chain.Winner → Blockchain → Autopilot: Execute & reportThe solver executes the transaction on the blockchain and reports the transaction hash to Autopilot.Autopilot → Database: Store auction dataAutopilot stores all auction data: proposals from solvers, scores, surplus fees for limit orders, and the results of on-chain execution. This data is used to calculate solver payouts. Misbehavior by solvers is detected during the payout calculation stage.
Essentially, Autopilot acts as a referee in the competition between solvers. It sets the rules for each round — which orders participate and what prices should be used for scoring the results. The system is built on a smart balance between speed and security: solvers can compete and execute solutions quickly, while fairness is enforced both during the winner selection and after the auction ends. It's similar to a sports competition, where the referee records results in real-time, and a detailed review with potential penalties happens afterward. This approach allows the protocol to operate at high speed without sacrificing reliability.
Solvers
Solvers are off-chain services made up of two components: the driver and the solver engine.
Driver – coordinates the work of the solver: receives the auction from Autopilot, prepares data for the Engine, processes solutions, evaluates them, sends the solution to Autopilot, and executes it on the blockchain. There is open source code.
Solver Engine – implements order-matching algorithms to find optimal solutions. It receives data from the Driver, finds the best execution paths, and returns instructions to achieve the result on-chain. Various open-source solvers are available in CoW Protocol solvers. However, to win auctions, teams develop their own highly optimized algorithms with private liquidity in their solver engine.
The solver's work can be divided into 4 stages: preparation phase, solving phase, finalization and submission, execution (if the solver wins).
Detailed Solver Workflow
Preparation Phase
Autopilot → Driver: auctionAutopilot sends the new auction to all registered solvers. The Driver receives the "raw" auction with a minimal data set.Driver → Driver: pre-process auctionThe Driver enriches the auction with additional information: token metadata (decimals, symbols), filters out unfillable orders (insufficient balances, expired), and performs basic prioritization.Driver → Driver: fetch liquidityThe Driver gathers up-to-date liquidity data from cached sources: AMM pools (Uniswap, Balancer, Curve), aggregators, and the team's private liquidity sources.
Solving Phase
Driver → Engine: auctionThe Driver passes the fully prepared auction to the Solver Engine with all the necessary information for decision-making.Engine → Driver: set of solutionsThe Solver Engine analyzes the auction using its algorithms and returns a set of possible solutions with their quality scores.
Finalization and Submission
Driver → Driver: post-process solutionsThe Driver verifies the correctness of the solutions, simulates their execution, combines compatible solutions to improve efficiency, calculates the score, and selects the best solution to submit.Driver → Autopilot: submit solutionThe Driver submits the best solution with the calculated score:
// https://github.com/cowprotocol/services/blob/main/crates/driver/src/infra/api/routes/solve/dto/solve_response.rs
pub struct Solution {
solution_id: u64, // Unique solution ID
score: eth::U256, // Batch auction solution score
submission_address: eth::H160, // Solver address for execution
orders: HashMap<OrderId, TradedOrder>, // Executed orders with details
clearing_prices: HashMap<eth::H160, eth::U256>, // Execution prices proposed by the solver
} Autopilot → Driver: execute settlement (if winner)If the solver wins the auction, the Driver executes the solution on-chain.
The architecture separates responsibilities: the Driver handles protocol integration, while the Engine implements matching algorithms.
Score Calculation and Winner Selection Algorithm
Score Calculation
The key mechanism for competition between solvers is the calculation of the score (quality rating) of solutions, which determines the auction winner.
score = (surplus + protocol_fees) × native_price_buy_token
# surplus for a sell order is already in the buy token For sell orders
score = (surplus + protocol_fees) × p_limit × native_price_buy_token
# where p_limit = limit_buy_amount / limit_sell_amount Explanation: For buy orders, the surplus is in the sell token, so we first convert it to the buy token using the limit price ratio
p_limit, and then to ETH usingnative_price_buy_token.
Where:
surplus– the extra value the user receives above the limit priceprotocol_fees– protocol feesnative_price_buy_token– price of the buy token in ETH (from the auction)
Sell order: sell 1 ETH for USDC
- Limit price: 1 ETH = 2000 USDC
- Actual execution: 1 ETH = 2050 USDC
- User surplus: 2050 - 2000 = 50 USDC (surplus in the buy token)
- Protocol fees: 5 USDC
- USDC price: 0.0004 ETH
Score = (50 + 5) × 0.0004 = 0.022 ETH
# We use the USDC price since both surplus and fees are in USDC (buy token) Buy order: buy 100 USDC for DAI
- limit_buy_amount: 100 USDC
- limit_sell_amount: 102 DAI (maximum willing to pay)
- executed_sell_amount: 98 DAI (actual payment)
- executed_buy_amount: 100 USDC (received)
1. Surplus in the sell token: 102 - 98 = 4 DAI
2. Protocol fees: 0.5 DAI
3. p_limit = 100 USDC / 102 DAI = 0.98 USDC/DAI
4. USDC price: 0.0004 ETH
Score = (4 + 0.5) × 0.98 × 0.0004 = 0.001764 ETH
# We use the USDC price since we convert the total surplus into USDC (buy token)
Step-by-step:
- 4.5 DAI surplus converted into buy tokens: 4.5 × 0.98 = 4.41 USDC
- 4.41 USDC converted into ETH: 4.41 × 0.0004 = 0.001764 ETH // https://github.com/cowprotocol/services/blob/main/crates/driver/src/domain/competition/solution/scoring.rs
fn score(&self, native_prices: &auction::Prices) -> Result<eth::Ether, Error> {
let native_price_buy = native_prices
.get(&self.signed_buy.token)
.ok_or(Error::MissingPrice(self.signed_buy.token))?;
let surplus_in_surplus_token = self
.user_surplus()?
.0
.checked_add(self.fees()?.0)
.ok_or(Error::Math(Math::Overflow))?;
let score = match self.side {
// surplus for sell orders is already in buy tokens, just convert to ETH
Side::Sell => native_price_buy.in_eth(eth::TokenAmount(surplus_in_surplus_token)),
Side::Buy => {
// surplus for buy orders is in sell tokens. Convert to buy tokens:
// buy_amount = surplus * buy_price / sell_price
let surplus_in_buy_tokens: eth::U256 = surplus_in_surplus_token
.full_mul(self.signed_buy.amount.0) // surplus * buy_price
.checked_div(self.signed_sell.amount.0.into()) // / sell_price
.ok_or(Error::Math(Math::DivisionByZero))?
.try_into()
.map_err(|_| Error::Math(Math::Overflow))?;
// Then convert buy tokens to ETH
native_price_buy.in_eth(surplus_in_buy_tokens.into())
}
};
Ok(score)
} Winner Selection Algorithm
After receiving solutions from all solvers, Autopilot initiates a multi-step selection process with independent score verification:
1. Score Recalculation for Verification Autopilot independently recalculates the score for each solution using the same token prices from the auction (not current market prices). Solutions for which the score cannot be recalculated are automatically discarded.
2. EBBO Fairness Check (Equal or Better than Best Offer) It verifies that the prices in the solution are equal to or better than the best offers from liquidity sources (Uniswap, Sushiswap, Balancer, etc.). Solutions that violate EBBO are rejected as "unfair".
3. Sorting and Winner Selection The solution with the highest recalculated score is selected.
// https://github.com/cowprotocol/services/blob/main/crates/autopilot/src/domain/competition/winner_selection/combinatorial.rs
fn partition_unfair_solutions(&self, mut participants: Vec<Participant<Unranked>>,
auction: &domain::Auction) -> PartitionedSolutions {
// SCORE RECALCULATION in autopilot for verification!
let scores_by_solution = compute_scores_by_solution(&mut participants, auction);
// Sort by RECALCULATED score
participants.sort_by_key(|participant| {
std::cmp::Reverse(participant.solution().computed_score().expect("computed").get().0)
});
// Fairness check с baseline scores (EBBO)
let baseline_scores = compute_baseline_scores(&scores_by_solution);
let (fair, unfair) = participants.into_iter().partition_map(|p| {
if aggregated_scores.iter().all(|(pair, score)| {
baseline_scores.get(pair).is_none_or(|baseline| score >= baseline) // EBBO check
}) {
Either::Left(p) // Fair solution
} else {
Either::Right(p) // Unfair solution – discarded
}
});
PartitionedSolutions { kept: fair, discarded: unfair }
} Winner selection logic implementation
The system ensures fairness through three layers of rules: smart contract, off-chain protocol (Autopilot), and social consensus (governance with penalties).
Conclusion
Batch auctions in CoW Protocol represent a complex but effective system for fair execution of trading intentions. The three-layer architecture (Orderbook, Autopilot, Solvers) provides an optimal balance of speed, security, and efficiency.
Key advantages of the system:
- Fair pricing through unified clearing prices
- MEV protection thanks to batch processing
- Competition among solvers for the best user outcomes
- Transparency through independent verification and EBBO checks
This architecture makes CoW Protocol a unique solution in the world of decentralized trading, where user interests are protected at every level of the system.
More articles by this author
CoW DAO and CoW Protocol: How Intent-Based Trading and MEV Protection Transform DeFi
Alexei Kutsenko
Solidity developer
How to Fork and Launch Uniswap V3 Smart Contracts: A Practical Guide
Alexei Kutsenko
Solidity developer
Bittensor: Overview of the Protocol for Decentralized Machine Learning
Alexei Kutsenko
Solidity developer
CoW Protocol Batch Auctions: How Orderbook, Autopilot, and Solvers Ensure Fair Trading
Alexei Kutsenko
Solidity developer
CoW DAO and CoW Protocol: How Intent-Based Trading and MEV Protection Transform DeFi
Alexei Kutsenko
Solidity developer
Smart Contracts Aren’t Deployed Yet, but Addresses Already Exist: Why CREATE2 (EIP-1014) Matters
Roman Yarlykov
Solidity developer
How to Fork and Launch Uniswap V3 Smart Contracts: A Practical Guide
Alexei Kutsenko
Solidity developer
Bittensor: Overview of the Protocol for Decentralized Machine Learning
Alexei Kutsenko
Solidity developer
Aerodrome Protocol: How a MetaDEX on Base Blends Uniswap, Curve, and Convex
Roman Yarlykov
Solidity developer
Articles
Algebra Finance: Modular DEX-as-a-Service with Plugins, Dynamic Fees, and Uniswap Compatibility
Roman Yarlykov
Solidity developer
Articles
ERC-6909: Minimal Multi-Token Interface and Why It Matters for Ethereum Projects
Pavel Naydanov
Solidity developer
Uniswap v4 Explained: Hooks, Singleton Architecture, Dynamic Fees & ERC-6909
Pavel Naydanov
Solidity developer
AI Agents: How AI Agents Conquered the Crypto Market + Key Projects
MetaLamp editorial team
AI and Blockchain: Key Takeaways from 2024 and Industry Forecasts for 2025
MetaLamp editorial team
The main events in The Open Network (TON) ecosystem in 2024
MetaLamp editorial team
A Guide to EigenLayer: How the ETH Restaking Protocol Attracted $15 Billion TVL
MetaLamp editorial team
The Open Network 2025: figures, events, analytics, forecasts
MetaLamp editorial team
Overview of Blockchain Bridges: Interaction Between Different Networks
Roman Yarlykov
Solidity developer
5 Rules from the Founder: How an EdTech Project Can Attract Investments. The Case of the Online School “Logopotam”
Alexey Litvinov
CEO and founder of the online school Logopotam
Is it worth launching a project on Solana, despite the hype around memes?
MetaLamp editorial team
Mintless Jettons on TON: A New Feature Making TON Projects Even More Attractive
MetaLamp editorial team
3 reasons to choose a ready-made solution for mini-apps in Telegram instead of developing from scratch
Dmitriy Shipachev
CEO at Finch
Think of it like a hamster for traffic: how to attract an audience with a Telegram clicker game
Nico Bordunenko
Business Analyst at MetaLamp
Which Rollup to Choose for Your Project: Arbitrum, Optimism, Base, ZK EVM, and Others
MetaLamp editorial team
How We Adapted a Mobile RPG for Blockchain and Enabled NFT Sales
MetaLamp editorial team
How TON Payments Enable Fee-Free Micro-Transactions and Their Uses
MetaLamp editorial team
What You Need to Know Before Starting a Project on TON
MetaLamp editorial team
What is the Meaning and Benefits of MVP for Startups in 2024?
MetaLamp editorial team
RWA explained: Opportunities of Real-World Assets in 2024
MetaLamp editorial team
Creating a Crypto Transaction Widget for Google Sheets: The CPayToday Journey
MetaLamp editorial team
How Early-Stage Startups Can Stay on Track with Development
MetaLamp editorial team
How to Attract Investments: Insights from Successful 2023 Startups
Mykola Pryndiuk
Social Media Specialist
When and How to Find a Technical Partner for Your Startup
MetaLamp editorial team
Understanding the Necessity of Account Abstraction in the Crypto World
Pavel Naydanov
Solidity developer
Ways to Speed Up Development: Outstaffing Pros and Cons
MetaLamp editorial team
Freelancer, Agency, or Contract Employees: Who to Hire for Startup MVP Development
Yana Geydrovich
Partnership manager at MetaLamp
From Corporate Blog to Brand Media: The Birth of Metalamp Magazine
Mykola Pryndiuk
Social Media Specialist
La Migliore Offerta: The Impact of Cryptocurrency on Business and Economy in 2023
Roman Shtih
CEO Metalamp
How We Use Our Training Program to Recruit Plutus Engineers
Svetlana Dulceva
The Education Program Supervisor
Discover Why IT Companies Appreciate Our Junior Developers
Svetlana Dulceva
The Education Program Supervisor
How We Designed a No-Cost Education Program for Web Development
Sergey Cherepanov
CTO MetaLamp
Articles