Skip to content

An EVM Linux-powered coprocessor as an orderbook for UniswapV4

License

Notifications You must be signed in to change notification settings

henriquemarlon/swapx

Repository files navigation



An EVM Linux-powered coprocessor as an orderbook for UniswapV4
Cartesi Coprocessor orderbook powered by EigenLayer cryptoeconomic security

license last-commit

Caution

This is an experimental project under continuous development and should be treated as such. Its use in production/mainnet is not recommended. Learn about the known limitations of the application by accessing: DISCLAIMER.

Table of Contents

Overview

SwapX integrates a decentralized orderbook with Uniswap v4 hooks, replacing the traditional AMM logic with an asynchronous swap system and limit orders. Leveraging EigenLayer's cryptoeconomic security through the Cartesi Coprocessor, it enables swaps to be scheduled, optimized, and auditable, ensuring greater liquidity efficiency and reducing trader uncertainty. This approach eliminates the need for immediate execution, allowing for more sophisticated and flexible strategies for market makers, liquidity protocols, and derivatives.

Architecture

image

1 - The SwapXHook.sol implementation is a Uniswap hook based on AsyncSwap1. Instead of executing the swap at the market price, it implements a custom logic for limit orders:

  • The order value is transferred to the hook upon creation;
  • The user can cancel the order and receive the funds back;
  • When an order is created, a task is issued to the SwapX order book, which will efficiently and intelligently match orders, including aggregating multiple orders and ensuring that the best orders are matched with the incoming order.

2 - The Assets in this case are token contracts that will be transacted in the swap between users through the pool and contracts that are part of the UniswapV4 SDK.

3 - The Operator, which is part of the Cartesi Coprocessor, operates under the crypto-economic security of the EigenLayer restaking protocol. This gives it the ability to perform operations with guarantees of the computation performed.

4 - The Cartesi Coprocessor is an EigenLayer AVS that operates through a network of operators, leveraging the runtime provided by the Cartesi Machine. It is triggered when a new TaskIssued(bytes32, bytes, address) event is emitted. To learn more, visit: https://docs.mugen.builders/cartesi-co-processor-tutorial/introduction.

5 - The Base Layer Access is enabled through domain 0x27, present in the GIO, which allows calls viaeth_getStorageAt. Based on this, the application can access the base layer (read-only), and this is how previously created orders (up to the previous block) are loaded into the application to be processed within the order book. The request specification is as follows:

{"domain": "0x27", "id": "0x<block_hash:32_bytes><address:20_bytes><storage_slot:32_bytes>"}

Prerequisites

  1. Install Docker Desktop for your operating system.

    To install Docker RISC-V support without using Docker Desktop, run the following command:

     docker run --privileged --rm tonistiigi/binfmt --install all
  2. Download and install the latest version of Node.js

  3. Cartesi CLI is an easy-to-use tool to build and deploy your dApps. To install it, run:

    npm i -g @cartesi/cli
  4. Install the Cartesi Coprocessor CLI

Running

  1. Start the devnet coprocessor infrastructure:

    make infra
  2. Build and Publish the application:

    cartesi-coprocessor publish --network devnet

Warning

Before the next step, create a .env with the command bellow:

make env

This should look like:

RPC_URL=http://localhost:8545
PRIVATE_KEY=0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
  1. Deploy UniswapV4 contracts, SwapXHook.sol and SwapXTaskManager.sol contracts:`
  • 3.1 Deploy UniswapV4 contracts:

    make v4

Note

The following step requires some extra information provided by the command bellow:

cartesi-coprocessor address-book

Output sample:

Machine Hash         0xdb1d7833f57f79c379e01b97ac5a398da31df195b1901746523be0bc348ccc88
Devnet_task_issuer   0x95401dc811bb5740090279Ba06cfA8fcF6113778
Testnet_task_issuer  0xff35E413F5e22A9e1Cc02F92dcb78a5076c1aaf3
payment_token        0xc5a5C42992dECbae36851359345FE25997F5C42d
  • 3.2 Deploy SwapXHook.sol and SwapXTaskManager.sol:

    make hook

    Output sample:

     [⠊] Compiling...
     No files changed, compilation skipped
     Enter Coprocessor address: <devnet_task_issuer>
     Enter Machine Hash: <machine_hash>

Interacting

Important

If the previous steps were followed precisely, specifically the one that sets up the local infrastructure, accessing http://localhost:5100 will present you with a block explorer where you can monitor the transactions occurring on the contract of interest. In this project, that contract is the one that implements the Uniswap hook via AsyncSwap1. After that, just search for the contract using that address on Otterscan.

make demo

Note

You should observe, after a while, four calls targeting the signature method 0x7417ccfb, each covering one of the following scenarios:

Scenario Description
0 Buy Order Fulfilled by One Sell Order A buy order is completely fulfilled by a single sell order.
1 Buy Order Fulfilled by Multiple Sell Orders A buy order is completely matched by a combination of multiple sell orders.
2 Sell Order Fulfilled by One Buy Order A sell order is completely fulfilled by a single buy order.
3 Sell Order Fulfilled by Multiple Buy Orders A sell order is completely matched by a combination of multiple buy orders.
4 Buy Order Partially Fulfilled by Multiple Sell Orders A buy order is only partially matched, while multiple sell orders fulfill part of it.

You can see even more details by accessing the logs tab of one of these transactions, and you'll come across something like this:

logs

Footnotes

  1. You can see here the reference for enabling the AsyncSwap in a UniswapV4 hook, and here is where it was defined within the application. 2