Understanding Uniswap’s Universal Router & Permit2(Part -1)

The Last Standing Bull
5 min readJul 30, 2023

--

Photo by Juliana Araujo the artist on Unsplash

The decentralized finance (DeFi) space has witnessed remarkable growth, with various protocols and platforms aiming to provide efficient and seamless token-swapping experiences. Among these innovations, Uniswap’s Universal Router and its integration with Permit2 have emerged as game-changers, offering novel functionalities and addressing critical challenges. In this article, we will deep dive into the intricacies of the Universal Router and Permit2, providing a comprehensive overview of their functionalities, technical details, and executing a transaction using Universal Router and Permit2.

Prerequisites

I assume that you have a fundamental understanding of the following concepts before reading further:

  1. DEX
  2. AMM
  3. ERC 20 / 721 / 1155 / 712 / 1271 / 2612

You should be able to understand and navigate the rest of this series after you have these requirements met.

Existing swap routers often face limitations, supporting either NFTs or ERC20 tokens exclusively and requiring multiple transactions for trades involving both types. To address these inefficiencies, Uniswap introduces the Universal Router and integrates it with Permit2, aiming to provide a unified and enhanced user experience.

Universal Router

The Universal Router represents a groundbreaking solution in the world of token swaps. It enables users to execute multiple token swaps on Uniswap V2 and V3, as well as buy NFTs from various marketplaces, all within a single transaction. By unifying ERC20 and NFT swaps, the Universal Router eliminates the need for multiple transactions, streamlining the trading process and reducing gas costs. It offers flexibility by supporting split routes across different Uniswap versions, optimizing trade execution based on liquidity and price.

Image Source

The entry point of the Universal Router contract is typically the execute function. This function serves as the main interface for executing commands and initiating token swaps, NFT purchases, and other operations within the Universal Router. This function takes 3 parameters as input.

execute(bytes memory commands, bytes[] memory inputs, uint256 deadline)

Here’s a breakdown of the parameters:

commands: A bytes array that represents the encoded commands to be executed. Each individual byte within the array corresponds to a command that the transaction will execute.

inputs: A bytes array containing the encoded input parameters for the commands. Each element in the array corresponds to the encoded parameters for the corresponding command in the commands array.

deadline: An optional parameter specifying the timestamp deadline by which the transaction must be executed. Transactions executed after the specified deadline will revert.

Let’s understand the Universal Router’s command encoding and execution process

Command encoding

The command encoding process of the Universal Router involves encoding each command into a bytes1 value that represents the command’s flag, reserved space, and command identifier bits. Here’s an overview of the command encoding process:

Command Structure: Each command in the Universal Router is represented by a bytes1 value. The bytes1 value contains 8 bits, numbered from 0 to 7, which are used to encode the command’s flag, reserved space, and command identifier.

  1. Flag: The first bit, labeled as “Flag,” is a single bit that indicates whether the command is allowed to revert. If the flag is set to 0 (false), and the command reverts, the entire transaction will revert. If the flag is set to 1 (true) and the command reverts, the transaction will continue, allowing partial fills. It’s important to include further commands to remove any unused funds in the Universal Router contract when using the flag.
  2. Reserved Space: The second bit, labeled as “Reserved Space,” provides one bit of reserved space for potential future use. It allows for future expansion of the command encoding structure by increasing the space available for commands or adding new flags.
  3. Identifier: The remaining 6 bits, labeled as “Identifier,” represent a unique identifier for each command. The identifier uniquely identifies the type of operation associated with the command. The Universal Router has predefined command identifiers for various operations such as token swaps, NFT purchases, wrapping/unwrapping ETH, and more.

NOTE: During the encoding process, the flag, reserved space, and identifier bits are combined to create the bytes1 value representing the command.

Input bytes array structure

  1. The input bytes array, denoted as inputs[], contains multiple elements, where each element represents the encoded parameters for a particular command. The length of the inputs[] array should match the length of the commands[] array.
  2. For each command, the parameters are encoded using the ABI encoding format. ABI encoding ensures compatibility and consistency when serializing and deserializing data in Ethereum. The encoded parameters capture the necessary information required for executing the command accurately.
  3. Parameter Encoding Sequence: The parameters for each command are encoded in a specific sequence that aligns with the order expected by the command’s implementation. This ensures that the corresponding command receives the correct parameters during execution.
  4. Developers can use ABI encoding libraries such as ethers to encode the parameters. These tools handle the conversion of parameter values into their ABI-encoded representations.

Deadline

The optional “deadline” parameter enforces time-bound execution to ensure transactions are executed within specified timeframes.

Permit2

Permit2 is a next-generation token approval and meta-transaction system that enhances the token approval process in Ethereum-based applications. It provides a low overhead and standardized approach to token approvals, making them easier, more secure, and more consistent across different applications. Permit2 introduces several key features and improvements compared to traditional token approval mechanisms. Here are some of the key aspects of Permit2:

  1. It simplifies and standardizes the approval process by leveraging permit-style approvals, even for tokens that do not support EIP-2612. With Permit2, users can approve tokens using a single transaction flow, eliminating the need for separate approval transactions and reducing gas costs.
  2. By abstracting the token approval flow from the router contracts, Permit2 enables users to approve tokens using Permit2 and pass the signature through to the Universal Router.
  3. Permit2 allows for batched token approvals and transfers, enabling users to manage multiple tokens and recipients with a single signature. This feature streamlines multi-token operations and reduces the number of transactions required, optimizing gas usage.
  4. Permit2 introduces non-monotonic nonces for signature-based transfers, enhancing security by ensuring that signed permits do not need to be transacted in a strict order.

Next Steps

In the next part, we will code the swap function using permit2 and Universal router.

References

https://blog.uniswap.org/permit2-and-universal-router

--

--

The Last Standing Bull

programming tutorializer, meme sommelier, and chronic sufferer of coprolalia.