Swap Execution
#
Using the RouterWe recommend using the router for swapping to and from different assets, which has different swapping functions for ETH, tokens, and tokens that have fee-on-transfer features.
Before executing the swap, it is recommended that an external price source is used to fix the minimum output tokens receivable when selling a fixed amount of tokens, or maximum amount of input tokens to be used when purchasing a fixed amount of tokens.
Your smart contract should also:
- Have enough ETH / tokens when executing the swap
- Be able to receive ETH, when it is the destination address for swapping to ETH
- Granted approval to the router when swapping from tokens
#
Obtaining Pool AddressesIt is necessary to specify which pools are to be used for the token swap. Read more about fetching pool addresses before proceeding.
Since each pool represents a token pair, it stands to be the case that the poolsPath
specified for token swaps must be 1 size smaller than path
, ie. poolsPath.length = path.length - 1
. Refer to the examples below.
#
ExamplesWe will cover 3 scenarios:
- Swap 1 ETH for DAI
- Swap USDC to obtain 1 ETH, with WBTC as an intermediary
- Swap 1 CORE (fee-on-transfer token) for USDT
#
1 ETH -> DAI#
swapExactEthForTokensA common error when swapping from ETH is forgetting to actually send ETH when calling the function. The value
field should match the amount of ETH sent.
#
USDC -> WBTC -> 1 ETH#
Transferring tokensBefore swapping, the contract should be in possession of USDC. The caller can either send the tokens beforehand, or give allowance to the contract to call the transferFrom
method. The short code snippet below showcases the latter.
#
Granting ApprovalThe next step is then to give the router some USDC allowance.
path
and poolsPath
#
Since the intended token path is usdc -> wbtc -> eth, path = [usdc, wbtc, weth]
. We also need to specify the usdc-wbtc and wbtc-eth pools to be used. Deciding which pools to use can be found in this section. Eg. poolsPath=[usdc-wbtc-pool, wbtc-weth-pool]
, where usdc-wbtc-pool
and wbtc-weth-pool
are the pool addresses to be used.
#
swapExactTokensForETHNote that if the destination address is a contract, it should have the receive() external payable { ... }
or fallback function declaration in order to receive ETH.
#
1 CORE -> USDTThis example is similar to the previous example of USDC -> WBTC -> ETH. The only exception is that CORE is a fee-on-transfer token, and thus requires special handling.
#
swapExactTokensForTokensSupportingFeeOnTransferTokensWe assume that the previous steps of transferring tokens and token approval to the router has been performed.