Fusion swap resolving: the offchain component
The second article in our series explaining Fusion mode is focused on the offchain component of swap resolving.
In the series’ first article, we introduced the concept of a resolver - a fully automated algorithm that consists of a server app (that determines which orders to fill and when), a set of smart contracts that execute trades and an externally owned account (or a multisig) that sets up the contracts.
To make a Fusion swap, a user enters order details in the swap form. Subsequently, the frontend app will send a request to the backend and instantly show estimated swap results.
Let’s take a look at an example.
Assuming, a user wants to swap 1000 DAI into WETH and enters the corresponding details in the 1inch dApp. The UI immediately assesses this swap and provides the following information:
- how much, in the best case scenario, the user would get (0.579608 WETH) + optimistic rates (est. WETH buy price) - that would be +1% above the current market return
- how much, in the worst case scenario, the user would get (0.571922 WETH) + pessimistic rates (min. WETH buy price) - that would be -1.33% below the current market return
- the maximum length of the auction (10 minutes).
The user has a variety of choices:
- Trust 1inch backend to determine the best preset, based on the tokens being swapped and the swap amount, and select “Auto”
- Select the “Fair” or “Auction” preset to increase the auction time
- Manually input the maximum and minimum return amounts and adjust the auction time.
Anyway, how does the app get estimated swap results?
As mentioned above, the frontend app (= UI) sends order parameters to the backend - specifically, to the 1inch quoter service. In our case, it sends DAI as the source token, WETH as the destination token and 1,000 DAI as the swap amount.
“Under the hood,” there are 3 presets: Fast, Fair and Auction. If the Auto preset is selected, the quoter “decides,” which of the 3 presets suits this particular swap best, and returns a corresponding value. If the Custom preset is selected, the user sets parameters for the quoter to work with.
The quoter is a sophisticated backend service that is designed to maximize the swap output in the user’s favor. Its goal is to define a proper limit price curve based on the current market price that the quoter requests from Pathfinder.
Take a look at the chart below. It shows a price curve generated by the quoter service with the Fast preset.
- The purple line is the price curve. It determines the amount to be received by the user in a certain block. It slowly decreases as the auction time elapses.
- The top horizontal dotted line marks the auction start amount in the Fair preset - 1.92M USDC.
- The middle horizontal dotted line represents the market amount that the user would get based on the market price received from Pathfinder (pf) - about 1.817M USDC.
- The bottom horizontal dotted line shows the minimum amount to receive at the end of the auction (fair min. return amount) - about 1.797M USDC.
- The purple diamonds on the curve are block timestamps. The auction lasts for 15 blocks, from 0 to 15, which resulted in roughly 180 seconds (3 minutes) because an average block validation time in Ethereum is 12 seconds. In each block, the amount the resolver must return to the user is different. Whatever the resolver receives on top of this amount - they can save it as a profit.
- The pink diamonds are key points. These are the points when the price curve changes its angle, representing the price drop speed. At first, the amount decreases quite quickly, then, at the 2nd block, there is a key point that decreases the speed, and so on. There are key points in the 2nd, 4th, 6th, 8th and 10th, 12th and 14th blocks.
To summarize it:
- The quoter receives order parameters from the UI and the current market price from Pathfinder.
- Based on the above, the quoter returns a curve that determines the amount the resolver must send to the user in each given block.
- The curve and its key points are determined by the order’s parameters and the preset selected in the UI.
The logic of the quoter is constantly fine-tuned by the 1inch backend team as we get more and more big data from our order filling history.
You might wonder how a resolver would earn on this. The earning logic is facilitated by the resolver’s backend. Briefly, there are certain arbitraging strategies that can maximize both the resolver’s and the user’s income, creating win-win situations.
While the user estimates their return amount based on order parameters, the frontend application keeps receiving estimates from the quoter every 12 seconds and displays them to the user.
At some point, the user decides to sign the order and the UI sends it to the backend to be subsequently filled by resolvers. The entire sequence looks as follows:
- The user estimates the order in the UI.
- The UI sends the order parameters to the quoter service.
- The quoter requests a market price (and return amount) from Pathfinder.
- Pathfinder provides a market price to the quoter.
- The quoter calculates the price (return amount) curve and returns it to the frontend.
- The user signs the order with their wallet (account).
- The UI sends a signed order to the relayer service at the backend.
- The resolver’s backend steps in and polls the relayer to get orders or subscribes to websocket updates from the relayer.
- The relayer sends to all the orders available for filling the resolver’s backend.
- The resolver’s backend decides which order to fill at which block and gives the respective instructions to its worker.
It’s important to notice that there is a very specific timeframe between steps 5 and 6 to cover the time needed for signing the order. After the user clicks “Confirm swap,” they only have 24 seconds to sign it in the wallet. Why exactly 24 seconds? Because 24 seconds covers 95% of signing order delay cases, according to data we have collected.
What happens if a user hasn’t signed the order? The relayer won’t accept it because market prices change very quickly. A price curve estimated more than 2 blocks ago might become irrelevant: if the market price goes too far in favor of the user, the resolvers won’t fill it. If the market price goes too far against the user, resolvers would be happy to fill the order but the user would be disappointed. So, it’s critically important to sign the submitted order as soon as possible.
Now, let’s wrap up what was said above about the offchain part of resolving orders:
- The UI is used to get a user’s input regarding the tokens, amount and auction preset.
- Pathfinder is used to estimate the current market price.
- The quoter is used to determine the price curve based on the two above values, which, in turn, determines the return amount the resolver must send to the user (which is slowly decreasing block by block).
- The relayer is used to store the orders and post them to the resolvers’ backends at their request.
The series’ next article will be focused on the execution of orders on the blockchain.