# Red Snwapper

RedSnwapper is a facade for the execution router contracts (RouteProcessor), and handles single & multi token swaps.

## Functions

### snwap

```solidity
function snwap(
  IERC20 tokenIn,
  uint amountIn,
  address recipient,
  IERC20 tokenOut,
  uint amountOutMin,
  address executor,
  bytes calldata executorData
) external payable returns (uint amountOut)
```

1. Transfers `amountIn` of `tokenIn` to `executor`.
2. Launches `executor` with `executorData` and `value = msg.value`.
3. Checks that `recipient`'s `tokenOut` balance increased by at least `amountOutMin`.

#### Parameters

| Name            | Type          | Description                                                                  |
|-----------------|---------------|------------------------------------------------------------------------------|
| `tokenIn`       | `IERC20`      | The token being swapped                                                      |
| `amountIn`      | `uint`        | The amount of `tokenIn` to swap (0 means take from contract balance)         |
| `recipient`     | `address`     | The address receiving the swapped tokens                                     |
| `tokenOut`      | `IERC20`      | The token to receive after the swap                                          |
| `amountOutMin`  | `uint`        | Minimum amount of `tokenOut` that must be received                           |
| `executor`      | `address`     | The contract that will execute the swap logic                                |
| `executorData`  | `bytes`       | Data payload passed to the `executor`                                        |

#### Return Values

| Name          | Type   | Description                                   |
|---------------|--------|-----------------------------------------------|
| `amountOut`   | `uint` | The actual amount of `tokenOut` received      |

### snwapMultiple

```solidity
function snwapMultiple(
  InputToken[] calldata inputTokens,
  OutputToken[] calldata outputTokens,
  Executor[] calldata executors
) external payable returns (uint[] memory amountOut)
```

1. Transfers each of the `inputTokens` to `inputTokens[i].transferTo`.
2. Launches all specified `executors`.
3. Checks that the final `recipient`'s `tokenOut` balance(s) are each at least their corresponding `amountOutMin`.

#### Parameters

| Name           | Type                | Description                                                               |
|----------------|---------------------|---------------------------------------------------------------------------|
| `inputTokens`  | `InputToken[]`      | Array of input token structs, each describing what token to transfer      |
| `outputTokens` | `OutputToken[]`     | Array of output token structs, each describing the expected output        |
| `executors`    | `Executor[]`        | Array of executor structs to be launched sequentially                     |

#### Return Values

| Name         | Type            | Description                                   |
|--------------|-----------------|-----------------------------------------------|
| `amountOut`  | `uint[] memory` | Actual amounts of each output token received  |

## Deployments

<AddressTable data={RED_SNWAPPER_ADDRESS} />

## Examples

### Using a contract to call RedSnwapper

Below is an example Solidity contract that can be used to call RedSnwapper.

It expects "self" as the `source` parameter when calling the API, and will pre-fund RedSnwapper with the input tokens before executing the swap.
In case "sender" is used as the `source`, the contract can be simplified by removing the token transfer logic, although an `approve` call is still be needed.

The `source` parameter is disregarded when the input token is native (ETH), in which case the contract must be pre-funded with enough ETH to cover the swap.

```solidity
contract RedSnwapperProxy {
  constant address NATIVE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
  constant address RED_SNWAPPER = 0xac4c6e212a361c968f1725b4d055b47e63f80b75;

  function swap(bytes calldata data) external payable returns (uint256 amountOut) {
    // Skip the first 4 bytes (function selector), decode the input token and amountIn
    (address tokenIn, uint256 amountIn) = abi.decode(data[4:], (address, uint256));

    // If the "source" parameter used to call the API is "self", we need to pre-fund the contract
    uint256 nativeAmount = 0;
    if (tokenIn == NATIVE) {
      require(msg.value >= amountIn, "Not enough ETH sent");
      nativeAmount = amountIn;
    } else {
      IERC20(tokenIn).transfer(RED_SNWAPPER, amountIn);
    }

    // Call RedSnwapper
    (bool success, bytes memory returnData) = RED_SNWAPPER.call{value: nativeAmount}(data);
    require(success, "RedSnwapper call failed");

    amountOut = abi.decode(returnData, (uint256));
  }
}

```
