DEV Community

Elnaril
Elnaril

Posted on • Originally published at reddit.com

What Uniswap Universal Router commands are actually used?

Context

There are more than 30 functions implemented in the Universal Router (UR) at the moment, in the repository main branch.

As the author of the Python Uniswap Universal Router SDK, I always wonder what should be the next one(s) this library should support.

Until now, I've added the most obvious functions:

  • the ones that allow to swap ERC-20 tokens:
    • V3_SWAP_EXACT_IN
    • V3_SWAP_EXACT_OUT
    • V2_SWAP_EXACT_IN
    • V2_SWAP_EXACT_OUT
  • those often needed before or after:
    • WRAP_ETH
    • UNWRAP_WETH
    • PERMIT2_PERMIT
  • and a couple ones that allow more possibilities:
    • SWEEP
    • PAY_PORTION

But for the next supported functions, I decided to list those that are actually used, and order them from the most to the least called.

Methodology

To reach this goal, I wrote a simple Python script that looks into all blocks included in Mainnet during November 2023, gets all transactions sent to the Universal Router, discards those with a too small input field, and decodes them. And counts how many times each command (function) is used.

This script can be found here, so the results can be reproduced. Just change the RPC providers.

No fancy optimizations were implemented in the script apart from good ol' asyncio and it does not check whether the transactions were rejected by the EVM or not, to avoid requesting the receipts. This is a bit annoying in terms of clean data, but allowed me to get the results in less than half a day.

Another limitation with this method: it does not take into account transactions using the UR through custom contracts.

Results

The scripts scanned:

  • 214 307 blocks (from 18 473 543 to 18 687 850)
  • 2 453 214 transactions sent to the UR
  • 5 435 322 commands

And the raw results is given in the below dict, with the decimal commands as keys and the number of calls as values:

Results: {11: 1362528, 8: 1886773, 9: 97389, 1: 52226, 12: 856319, 10: 593542, 0: 494207, 5: 8346, 4: 36076, 6: 47881, 16: 25, 25: 2, 14: 8}
Enter fullscreen mode Exit fullscreen mode

There were 32 transactions that could not be decoded, either because they are wrongly formatted and rejected by the EVM, or their format does not respect the specifications (as I understand them) but still were accepted by the EVM (more on them in another post). Anyway they are not statistically relevant, so let's just disregard them for now.

The following table lists the results with the function names, ordered by counts (desc) and whether or not it is already supported by the codec:

Dec - Hex Code Name Counts Supported
8 - 0x08 V2_SWAP_EXACT_IN 1886773
11 - 0x0b WRAP_ETH 1362528
12 - 0x0c UNWRAP_WETH 856319
10 - 0x0a PERMIT2_PERMIT 593542
0 - 0x00 V3_SWAP_EXACT_IN 494207
9 - 0x09 V2_SWAP_EXACT_OUT 97389
1 - 0x01 V3_SWAP_EXACT_OUT 52226
6 - 0x06 PAY_PORTION 47881
4 - 0x04 SWEEP 36076
5 - 0x05 TRANSFER 8346
16 - 0x10 SEAPORT_V1_5 25
14 - 0x0e placeholder 8 N/A
25 - 0x19 SUDOSWAP 2

As a Pie Chart:

Usage Distribution of the Uniswap Universal Router Commands

So, basically, most of the used commands (99.8% of the calls) are already supported by the Python UR SDK. The only one really missing is TRANSFER with 8346 counts (< 0.2%), the others are anecdotal:

  • SEAPORT_V1_5 with 25 counts
  • a placeholder with no function yet (8 counts)
  • SUDOSWAP with 2 counts

Other interesting results

1/ The 4 swap functions (V2_SWAP_EXACT_IN, V3_SWAP_EXACT_IN, V2_SWAP_EXACT_OUT and V3_SWAP_EXACT_OUT) were called 2 530 595 times:

  • 1 984 162 (78.4%) for a V2 pool, most of it (74.6%) through the V2_SWAP_EXACT_IN function
  • 546 433 (21.6%) for a V3 pool

2/ The second most used function is WRAP_ETH with 1 362 528 calls, which is 53.8% of all swap commands. Knowing that several swap commands can be chained after a single WRAP_ETH, this suggests that ETH is largely used to initiate a swap.

3/ There are 2.2 commands/functions per transaction on average.

4/ Still on average, each block contains 11.4 transactions sent to the Universal Router!

Conclusion

As expected, the functions related to ERC-20 DeFi are extensively used. But, basically, nothing else is used apart the TRANSFER function: no batch ones, no permit2 transfers, no NFTs, ...
So, I guess I'll implement TRANSFER sooner or later, but what about the other ones?
Do you think there is an interest in them? If, yes which ones and why are they not already used?

Top comments (0)