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

# Swap Tokens for Tokens

> Swap HTS fungible tokens for HTS fungible tokens

Below are three methods available to swap tokens for tokens:

* [Swap exact tokens for tokens](/v/developer/saucerswap-v1/swap-operations/swap-tokens-for-tokens#swap-exact-tokens-for-tokens)
* [Swap tokens for exact tokens](/v/developer/saucerswap-v1/swap-operations/swap-tokens-for-tokens#swap-tokens-for-exact-tokens)
* [Swap exact tokens for tokens supporting custom fees](/v/developer/saucerswap-v1/swap-operations/swap-tokens-for-tokens#swap-exact-tokens-for-tokens-supporting-custom-fees)

<Info>
  **Contract ID:** [SaucerSwapV1RouterV3](https://hashscan.io/mainnet/contract/0.0.3045981)
</Info>

<Note>
  Consider the token's decimal places when determining input and output values.

  Input and output amounts passed to the solidity function should all be in the token's smallest unit. For the SAUCE token, which has 6 decimal places, an input of 123.45 SAUCE should be entered as 123450000 (123.45 multiplied by 10^6).
</Note>

<Note>
  Granting an spender allowance to the router contract **is required** when the input token is not native HBAR for security reasons enforced at the native code layer . Ensure that the allowance amount is in token's smallest unit.
</Note>

<Warning>
  Ensure that the "to" account has the output token id associated prior to executing the swap. Failure to do so will result in a TOKEN\_NOT\_ASSOCIATED\_TO\_ACCOUNT error.
</Warning>

***

## Swap Exact Tokens for Tokens

Swap an exact amount of tokens for a minimum token amount.

Solidity function name: **swapExactTokensForTokens**

| Parameter Name             | Description                                              |
| -------------------------- | -------------------------------------------------------- |
| *uint amountIn*            | The exact input token amount in its smallest unit        |
| *uint amountOutMin*        | The minimum token amount to receive in its smallest unit |
| *address\[] calldata path* | An ordered list of token EVM addresses                   |
| *address to*               | EVM address for the token recipient                      |
| *uint deadline*            | Deadline in unix seconds                                 |

<CodeGroup>
  ```solidity IUniswapV2Router01.sol theme={null}
  function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  ) external returns (uint[] memory amounts);
  ```

  ```solidity UniswapV2Router02.sol theme={null}
  function swapExactTokensForTokens(
      uint amountIn,
      uint amountOutMin,
      address[] calldata path,
      address to,
      uint deadline
  ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
      amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
      require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');

      safeTransferTokenRouter(
    	  path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
      );
      _swap(amounts, path, to);
  }
  ```
</CodeGroup>

<Warning>
  Set the minimum output token amount (**amountOutMin**) with caution.

  A high minimum might lead to a swap failure due to insufficient liquidity or rapid price movements. Conversely, setting the minimum too low can expose you to significant slippage, potentially resulting in a financial loss as you might receive far fewer tokens than expected.
</Warning>

### Code Overview

<Tabs>
  <Tab title="JavaScript SDK">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Hedera JavaScript SDK](https://github.com/hashgraph/hedera-sdk-js)
    * [Token approve allowance](https://docs.hedera.com/hedera/sdks-and-apis/sdks/cryptocurrency/approve-an-allowance) &#x20;
    * [Associate tokens to an account](https://docs.hedera.com/hedera/sdks-and-apis/sdks/token-service/associate-tokens-to-an-account)
    * [Calling a smart contract function](https://docs.hedera.com/hedera/sdks-and-apis/sdks/smart-contracts/call-a-smart-contract-function)

    ```typescript Typescript theme={null}
    import { 
      ContractFunctionParameters, 
      ContractExecuteTransaction,
      AccountAllowanceApproveTransaction,  
      TokenAssociateTransaction,
      .. 
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Output token is associated
    // - Router contract has spender allowance for the input token

    const params = new ContractFunctionParameters();
    params.addUint256(amountIn); //uint amountIn
    params.addUint256(amountOutMin); //uint amountOutMin
    params.addAddressArray(tokenPath); //address[] calldata path
    params.addAddress(toAddress); //address to
    params.addUint256(deadline); //uint deadline
        
    const record = await new ContractExecuteTransaction()
     .setContractId(routerContractId)
     .setGas(gasLim)
     .setFunction('swapExactTokensForTokens', params)
     .execute(client);
     
    const record = await response.getRecord(client);
    const result = record.contractFunctionResult!;
    const values = result.getResult(['uint[]']);
    const amounts = values[0]; //uint[] amounts
    const finalOutputAmount = amounts[amounts.length - 1];
    ```
  </Tab>
</Tabs>

***

### Swap Tokens for Exact Tokens

Swap a maximum amount of tokens to receive an exact tokens amount.

Solidity function name: **swapTokensForExactTokens**

| Parameter name             | Description                                             |
| -------------------------- | ------------------------------------------------------- |
| *uint amountOut*           | The exact output amount to receive in its smallest unit |
| *uint amountInMax*         | The maximum allowed input amount in its smallest unit   |
| *address\[] calldata path* | An ordered list of token EVM addresses                  |
| *address to*               | EVM address for the token recipient                     |
| *uint deadline*            | Deadline in unix seconds                                |

<CodeGroup>
  ```solidity IUniswapV2Router01.sol theme={null}
  function swapTokensForExactTokens(
    uint amountOut,
    uint amountInMax,
    address[] calldata path,
    address to,
    uint deadline
  ) external returns (uint[] memory amounts);
  ```

  ```solidity UniswapV2Router02.sol theme={null}
  function swapTokensForExactTokens(
    uint amountOut,
    uint amountInMax,
    address[] calldata path,
    address to,
    uint deadline
  ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
    amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path);
    require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT');

    safeTransferToken(
      path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
    );
    _swap(amounts, path, to);
  }
  ```
</CodeGroup>

<Warning>
  Set the maximum input token amount (**amountInMax**) with caution.

  A low maximum might lead to a swap failure if the required liquidity surpasses this limit or due to rapid price movements. Conversely, setting it too high can expose you to significant slippage, potentially leading to a financial loss as you might spend far more tokens than expected.
</Warning>

### Code Overview

<Tabs>
  <Tab title="JavaScript SDK">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Hedera JavaScript SDK](https://github.com/hashgraph/hedera-sdk-js)
    * [Token approve allowance](https://docs.hedera.com/hedera/sdks-and-apis/sdks/cryptocurrency/approve-an-allowance) &#x20;
    * [Associate tokens to an account](https://docs.hedera.com/hedera/sdks-and-apis/sdks/token-service/associate-tokens-to-an-account)
    * [Calling a smart contract function](https://docs.hedera.com/hedera/sdks-and-apis/sdks/smart-contracts/call-a-smart-contract-function)

    ```typescript Typescript theme={null}
    import { 
      ContractFunctionParameters, 
      ContractExecuteTransaction,
      AccountAllowanceApproveTransaction,  
      TokenAssociateTransaction,
      .. 
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Output token is associated
    // - Router contract has spender allowance for the input token

    const params = new ContractFunctionParameters();
    params.addUint256(amountOut); //uint amountOut
    params.addUint256(amountInMax); //uint amountInMax
    params.addAddressArray(tokenPath); //address[] calldata path
    params.addAddress(toAddress); //address to
    params.addUint256(deadline); //uint deadline
        
    const response = await new ContractExecuteTransaction()
     .setContractId(routerContractId)
     .setGas(gasLim)
     .setFunction('swapTokensForExactTokens', params)
     .execute(client);
     
    const record = await response.getRecord(client);
    const result = record.contractFunctionResult!;
    const values = result.getResult(['uint[]']);
    const amounts = values[0]; //uint[] amounts
    const finalInputAmount = amounts[0];
    ```
  </Tab>
</Tabs>

***

## Swap Exact Tokens for Tokens Supporting Custom Fees

Swap an exact amount of tokens for a minimum HBAR amount, supporting HTS tokens with custom fees on token transfer.

Solidity function name: **swapExactTokensForTokensSupportingFeeOnTransferTokens**

| Parameter Name             | Description                                              |
| -------------------------- | -------------------------------------------------------- |
| *uint amountIn*            | The input token amount in its smallest unit              |
| *uint amountOutMin*        | The minimum token amount to receive in its smallest unit |
| *address\[] calldata path* | An ordered list of token EVM addresses                   |
| *address to*               | EVM address for the token recipient                      |
| *uint deadline*            | Deadline in unix seconds                                 |

<CodeGroup>
  ```solidity IUniswapV2Router02.sol theme={null}
  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  ) external;
  ```

  ```solidity UniswapV2Router02.sol theme={null}
  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  ) external virtual override ensure(deadline) {
    
    safeTransferToken(
      path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn
    );
    uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
    _swapSupportingFeeOnTransferTokens(path, to);
    require(
      IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin,
      'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'
    );
  }
  ```
</CodeGroup>

<Warning>
  Set the minimum output token amount (**amountOutMin**) with caution.

  A high minimum might lead to a swap failure due to insufficient liquidity or rapid price movements. Conversely, setting the minimum too low can expose you to significant slippage, potentially resulting in a financial loss as you might receive far fewer tokens than expected.
</Warning>

### Code Overview

<Tabs>
  <Tab title="JavaScript SDK">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Hedera JavaScript SDK](https://github.com/hashgraph/hedera-sdk-js)
    * [Token approve allowance](https://docs.hedera.com/hedera/sdks-and-apis/sdks/cryptocurrency/approve-an-allowance) &#x20;
    * [Associate tokens to an account](https://docs.hedera.com/hedera/sdks-and-apis/sdks/token-service/associate-tokens-to-an-account)
    * [Calling a smart contract function](https://docs.hedera.com/hedera/sdks-and-apis/sdks/smart-contracts/call-a-smart-contract-function)

    ```typescript Typescript theme={null}
    import { 
      ContractFunctionParameters, 
      ContractExecuteTransaction,
      AccountAllowanceApproveTransaction,  
      TokenAssociateTransaction,
      .. 
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Output token is associated
    // - Router contract has spender allowance for the input token

    const params = new ContractFunctionParameters();
    params.addUint256(amountIn); //uint amountIn
    params.addUint256(amountOutMin); //uint amountOutMin
    params.addAddressArray(tokenPath); //address[] calldata path
    params.addAddress(toAddress); //address to
    params.addUint256(deadline); //uint deadline
        
    await new ContractExecuteTransaction()
     .setContractId(routerContractId)
     .setGas(gasLim)
     .setFunction('swapExactTokensForTokensSupportingFeeOnTransferTokens', params)
     .execute(client);
    ```
  </Tab>
</Tabs>
