The solver working on the current batch auction receives a pack of orders and should provide the best quality solution (see this
link). The example code of the solver is provided in the
solver crate.
Let's examine the example solver, which works with multiple orders, presented in
multi_order_solver.rs. Here we see the function
solve(). It launches a
loop that
adds additional context to orders (e.g., available reserves on Uniswap) and tries to
find a valid solution. If a solution is not found, it
removes the "worse" order from the pack and tries again.
The solver then
chooses the best solution by precalculating the results of swaps, including fees, and returns the final execution plan.
This execution plan includes giving allowances, a sequence of swaps in different DEXes to produce the best outcome, and other operations. Examples of the execution plans for Uniswap
V2/
V3,
0x, and
Balancer V2 are provided. An example of the solution sent by the solver can be found on this
page (examine the
/solve request).
Next is the auction itself, implemented in the
AuctionProcessor. The Auction entity
includes the block that this auction is valid for, the block of the last settlement, a pack of orders, and a pack of reference prices of used tokens.
First, let's focus on the
prioritization of orders using the
comparators based on prices, creation time, and owner of the order (solver's orders are prioritized to allow them to provide better solutions). In the same procedure, additional CoW AMM orders are
injected (the creation of
cow_amm_order can be examined
here). Additionally, orders are
filtered to ensure there are sufficient token amounts to perform the trades.
Next is the scoring of settlements, which is implemented
here and follows the rules (at the time this article was written) described in
CIP38. The main change is the exclusion of gas costs from the scoring of solutions, removing a complicated gas-related part that is not directly connected with solution effectiveness. This scoring calculates the difference between planned and actual amounts (see
here and
here).
Then comes the
competition. Incoming items are gathered asynchronously, and the scoring is then
applied to each presented solution. The best solution is then
selected. An important part then involves the
simulation of the winning solution at each new block until the deadline to ensure it works before submitting to a blockchain. This simulation is performed
here.