---
# System prepended metadata

title: '[Tycho] Ring V2 protocol integration'

---

# [DEX Integration] Ring V2 protocol

## :beginner: The goal
Fully implementing the Ring V2 protocol in Tycho, which means providing solutions for:
- Indexing
- Execution
- Simulation

Across Mainnet, Base, and Unichain blockchain networks.

## :beginner: How does Ring V2 protocol work

Ring V2 protocol is a UniswapV2 clone, with an exception, it uses wrapped tokens for all things swap related internally. The wrapper is called "Few protocol", and is represented by the `FewFactory` contract that deploys, and returns, respective wrapped tokens.

The following contracts are shared between the two protocols:
- `SwapV2Factory`
- `SwapV2Pair` - note that Pairs are exclusively made up of wrapped tokens, not regular IERC20 ones

`SwapV2Router` - this contract has a lot of changes compared to it's source, but the most notable one is that all wrapping is done inside of the methods respectfully. So the user doesn't have to wrap their own token at any time when interacting (altering liquidity).

A swap starting and ending with unwrapped IERC20 tokens is executed trough the `SwapV2Router` contract.

## :beginner: Indexing `tycho-integration-sdk`
The following events should be indexed in order to have full protocol state available at all times:
- `SwapV2Factory.PairCreated` - Triggered upon a UniswapV2 style pool creation - store pools in a map - note that wrapped token addresses are emitted
- `SwapV2Pair.PairEvents` - Triggered upon pool state change - should trigger price updates - note that wrapped token addresses are emitted
- `FewFactory.WrappedTokenCreated` - store tokens in a `FewToken:Token` map

This way we will have all needed data to fully represent the protocol. The starting blocks are determined by the `SwapV2Factory` deployment block on each chain respectfully.

The indexing configs are going to be in the `<chain>-ring-v2.yaml` format.

## :beginner: Simulating `tycho-simulation`
The Ring V2 protocol simulation is going to be natively integrated into the codebase. It's similar to the way Uniswap V2 exchanges are implemented. Including the `state` and `tycho_decoder` interfaces.

As far as we know, there is no need to implement the `ISwapAdapter` interface.

The implementation in `evm/protocol` will also include tests ensuring proper functionality.

## :beginner: Executing `tycho-exection`
The `encode_swap` function will be implemented, for interacting with the `Executor` contract. A `RingV2Executor` will be created, in order to match the interface for swap execution. The contract itself will be similar to `UniswapV2Executor`. The contract will be an implementation of the `IExecutor` contract shown below:
```solidity
/ SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.26;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

pragma abicoder v2;

interface IExecutor {
    /**
     * @notice Performs a swap on a liquidity pool.
     * @dev This method takes the amount of the input token and returns the amount of
     * the output token which has been swapped.
     *
     * Note Part of the informal interface is that the executor supports sending the received
     *  tokens to a receiver address. If the underlying smart contract does not provide this
     *  functionality consider adding an additional transfer in the implementation.
     *
     * @param givenAmount The amount of the input token to swap.
     * @param data Data that holds information necessary to perform the swap.
     * @return calculatedAmount The amount of the output token swapped, depending on
     * the givenAmount inputted.
     */
    function swap(
        uint256 givenAmount,
        bytes calldata data
    ) external payable returns (uint256 calculatedAmount);
}

interface IExecutorErrors {
    error InvalidParameterLength(uint256);
    error UnknownPoolType(uint8);
}
```
Also tests covering the new `RingV2Executor` contract will be included in the `foundry/test` directory, ensuring proper functionality.

## :beginner: Expected time goal
It's expected the integration will last 4 weeks. About a week per repo, plus a week of various unknowns that will certainly be unveiled.

## :beginner: Mainnet - Contract addreses
`Ring Swap Factory` `0xeb2A625B704d73e82946D8d026E1F588Eed06416`

`Few Factory` `0x7D86394139bf1122E82FDF45Bb4e3b038A4464DD`

`Ring Swap Router` `0x39d1d8fcC5E6EEAf567Bce4e29B94fec956D3519`

`UniversalRouter` `0xEff87A51f5Abd015F1AFCD5737BBab450eA15A24`

`Permit2` `0x000000000022D473030F116dDEE9F6B43aC78BA3`

`FewETHWrapper` `0xAda6059b4F6244Acd8934095Ed0162C5Df6B5ebB`

## :beginner: Base - Contract addreses
`Ring Swap Factory` `0x9BfFC3B30D6659e3D84754cc38865B3D60B4980E`

`Few Factory` `0xb3Ad7754f363af676dC1C5be40423FE538a47920`

`Ring Swap Router` `0x224749CDd5791480ECEBE452e5FFAEfEf94Cd254`

`UniversalRouter` `0x9a8C67C02250EC50f16b6143D139CbDB131f1e07`

`Permit2` `0x000000000022D473030F116dDEE9F6B43aC78BA3`

`FewETHWrapper` `0x20E6B1260d12910C0Ab13c1AbEBCFe24AE9c4fe7`

## :beginner: Unichain - Contract addreses
`Ring Swap Factory` `0xEeE400Eabfba8F60f4e6B351D8577394BeB972CD`

`Few Factory` `0x974Cc3F3468cd9C12731108148C4DABFB5eE556F`

`Ring Swap Router` `0xf9d7ff2f6A0c3631A807199276a493Af8097916F`

`UniversalRouter` `0xE17e4e8A43c1A0a1844BDe72ACA86Be3B81b28aF`

`Permit2` `0x000000000022D473030F116dDEE9F6B43aC78BA3`

`FewETHWrapper` `0xc43a3Dd1b16168e00297315d679840e30A89df42`
