> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soroswap.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# SoroswapRouter Comparison

> Comparison of SoroswapRouter with UniswapV2Router02: native token handling, deadlines, permit, and transfer fees.

## The Router Contract: Comparison between Soroswap and UniswapV2

Until now, we have developed the Factory and the Pair contract. The factory knows how many pairs it has created and can give us their contract addresses. Also, if we want to trade between token A and token B, and if that pair exists, the Factory will also give us the corresponding pair contract address.

But what happens if there are two pairs, A-B and B-C, and a user wants to make a trade between A and C? We could first trade A to B and then B to C! This is why we have the Router Contract.

The Router Contract allows swapping of tokens when a direct pair does not exist. It also handles liquidity provision and manages deposit and withdrawal functions for liquidity providers within the Soroswap ecosystem.

## The native token: ETH, WETH, and XLM.

In the `UniswapV2Router02`, there is a very important distinction between any ERC20 tokens and the native token ETH (and its wrapped version WETH). In particular, in the contract we find:

```javascript theme={null}
address public immutable override WETH;
```

With UniswapV2Router02, if you are using ETH, you'll need to use special functions:

* `addLiquidityETH` instead of `addLiquidity`
* `removeLiquidityETH` instead of `removeLiquidity`
* `removeLiquidityETHWithPermit` instead of `removeLiquidityWithPermit`
* Instead of just having `swapExactTokensForTokens` and `swapTokensForExactTokens`; Uniswap Router needs to add 4 extra functions: `swapExactETHForTokens`, `swapTokensForExactETH`, `swapExactTokensForETH`, `swapETHForExactTokens`.
* Instead of just having `swapExactTokensForTokensSupportingFeeOnTransferTokens`, Uniswap Router needs to add 2 extra functions: `swapExactETHForTokensSupportingFeeOnTransferTokens` and `swapExactTokensForETHSupportingFeeOnTransferTokens`

This is because it's very common that in Blockchains, the native token (in this case ETH in Ethereum) is treated differently, so the smart contract needs to trigger different functions when transferring the native token.

**What about in Soroban?**

Well, in Soroban, we won't need to have all these extra functions! This is because the native XLM token has its own token contract address and can be treated as any other token complying with the token interface.

You can find more information about this in the Soroban Token Playground Chapter 8, 9, 10, and 11.

**Conclusion:** none of the ETH-specific variants were needed. SoroswapRouter was written, and it is deployed on mainnet with the following public functions:

```
initialize
add_liquidity
remove_liquidity
swap_exact_tokens_for_tokens
swap_tokens_for_exact_tokens
get_factory
router_pair_for
router_quote
router_get_amount_out
router_get_amount_in
router_get_amounts_out
router_get_amounts_in
```

None of the following UniswapV2Router02 functions were written:

```javascript theme={null}
function addLiquidityETH
function removeLiquidityETH
function removeLiquidityETHWithPermit
function swapExactETHForTokens
function swapTokensForExactETH
function swapExactTokensForETH
function swapETHForExactTokens
function swapExactETHForTokensSupportingFeeOnTransferTokens
function swapExactTokensForETHSupportingFeeOnTransferTokens
```

Also, because we will treat XLM as any other token, we won't need to define its address. We won't need to write something like:

```javascript theme={null}
address public immutable override WETH;
```

Finally, there is also no need for this function:

```javascript theme={null}
receive() external payable {
        assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract
    }
```

as XLM can only be sent using the native contract.

## SafeMath

The Router relies on the same overflow and underflow protections as the rest of Soroswap, described in the [SoroswapLibrary comparison](/amm/technical-reference/vs-uniswap-v2/library).

## Deadlines

In Ethereum we can send a transaction with low gas price, and that transaction could be accepted 5, 10 or more minutes later. In order to avoid unwanted transactions after a period of time, Uniswap introduces the `deadline` parameter and the `ensure(deadline)` modifier:

```javascript theme={null}
modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED');
        _;
    }
```

In Soroban, we can think that having a transaction waiting for minutes is something that can never happen. But because we don't want to say **never**, Soroswap will include this "deadline modifier."

Modifiers do not currently exist in the `soroban-sdk`. So we'll need to build a special function using the `env.ledger().timestamp()` object.

## Permit

In `UniswapV2Router02` we use the `permit` method of the `UniswapV2ERC20.sol` contracts that is defined [here](https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2ERC20.sol):

```javascript theme={null}
 function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
        require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
        bytes32 digest = keccak256(
            abi.encodePacked(
                '\x19\x01',
                DOMAIN_SEPARATOR,
                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
            ) 
        );
        address recoveredAddress = ecrecover(digest, v, r, s);
        require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
        _approve(owner, spender, value);
    }
```

This function implements [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612). This avoids the user to use 2 transactions `approve` and \`transfer, which allows users to modify the allowance mapping using a signed message. this function allows a token holder to grant permission for a specific address (spender) to spend their tokens up to a certain amount (value) with a specified expiration time (deadline). The signature ensures the authenticity of the permit, and the function enforces that the permit hasn't expired and that it was signed by the legitimate token owner.

In Soroban we don't need to implement something like this, as we use the `require.auth()` method when sending tokens from the user into the smart contract.

**Conclusion:** We don't need to impement the `removeLiquidityWithPermit`, neither the `removeLiquidityETHWithPermit` functions (neither `removeLiquidityETHWithPermitSupportingFeeOnTransferTokens`)

## Fees on Transfer

In UniswapV2, there is a special function that allows the user to swap tokens that charge a fee when doing a transfer. This tokens are popular in the **deflactionist community**, and indeed it made Uniswap upgrade their original [UniswapV2Router](https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router01.sol) (latter called UniswapV2Router01) contract to a [UniswapV2Router02](https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol) version!

You can read all the discussion of the Uniswap design in [this issue](https://github.com/Uniswap/interface/issues/835)

In the code we see many functions that have the word `SupportingFeeOnTransferTokens`:

* `_swapSupportingFeeOnTransferTokens`
* `swapExactTokensForTokensSupportingFeeOnTransferTokens`
* `swapExactETHForTokensSupportingFeeOnTransferTokens`
* `swapExactTokensForETHSupportingFeeOnTransferTokens`
* `removeLiquidityETHSupportingFeeOnTransferTokens`

But in fact there is only two functions that do all the work: `_swapSupportingFeeOnTransferTokens` and `removeLiquidityETHSupportingFeeOnTransferTokens`

These functions work equal to `_swap` and `removeLiquidityETH` but succeeds for tokens that take a fee on transfer.

Because Soroswap wanted to support all types of tokens, the plan at the time was to carry this logic into the SoroswapRouter contract.

## library UniswapV2Library

UniswapV2Router uses the UniswapV2Library. Soroswap developed its own equivalent, compared function by function in the [SoroswapLibrary comparison](/amm/technical-reference/vs-uniswap-v2/library).

## Where this landed

The Rust was written. SoroswapRouter is deployed on mainnet, and its current interface is documented under [Contracts](/amm/technical-reference/contracts).
