Technology, Tutorials, Tool Support, for Developer

Seamless Token Swaps for Developers(1): Integrating KLAYswap V2 into Your Smart Contracts

Overview

Integrating KLAYswap programmatically into your decentralized application can be useful for a variety of reasons. This may include enabling users to seamlessly buy and sell their tokens without leaving your dApp. Also, this integration may be useful if your application provides services around these ERC20 and KIP7 tokens. For example, by buying sKAI programmatically through your dApp, users can then lend that sKAI on your site.

In this guide, you will programmatically integrate KLAYswap into your own smart contract and, execute a token swap from KLAY to sKAI on Klaytn Cypress (Mainnet). Then, in Part 2, you will learn how to build a minimalistic frontend that interacts with the contract using thirdweb and Next.js.

Prerequisites

  • Basic understanding of Smart Contracts. 
  • Familiar with any smart contract development environment (This tutorial uses thirdweb)

What is KLAYswap?

KLAYswap is an automated market maker (AMM) protocol for the Klaytn network. Simply put, it is a decentralized exchange (DEX) that supports immediate swapping between tokens by relying on liquidity pools created on-chain by liquidity providers other than the traditional order book structure.

 As an on-chain swap service, anyone who has any KLAY or KCT-type cryptocurrency can become a major participant in one of the following ways:

  • Liquidity Provider: You can provide liquidity by matching KLAY-KCT pairs with the token contracts created in KLAYswap’s Pool Menu. Usually, you will receive a Liquidity Provider (LP) token as a supply certificate and a reward share of the fees from the respective pool.
  • Trader: Tokens listed in the protocol can be traded with KLAY or KCT for as long as a respective pool exists.

Other than the KLAYswap dApp, they also provided the necessary smart contracts to develop on-chain integrations, if any. For the sake of this guide, we will be covering the KLAYswap V2 version, although it is not the latest version compared to V3.

If this interests you, let’s get started!

Integrating KLAYswap V2 

In this section, you will learn how to integrate KLAYswap into your smart contract programmatically using Solidity. At the end of this integration, users will be able to swap tokens from KLAY to sKAI and vice versa.

*Note: We will be trying this on Klaytn Mainnet (Cypress), as the testnet address for KLAYswap Universal Router wasn’t provided for test purposes. 

Let’s go over the swap integration by exploring the necessary components and swap methods.

KLAYswap UniversalRouter

The KLAYswap router provides a variety of methods to safely swap to and from different assets. This router optimally aggregates trades across V2 and V3 pools to give users access to highly-flexible and personalized transactions. It is important to note that before any swap method can be successfully called, the trader / user must first approve the router to N amount of tokens they wish to swap. 

Token Swap Methods

Swapping tokens on KLAYswap consists of using one of several swap methods in the Router smart contract. The methods used most often are swapExactETHForTokens, swapExactTokensForTokens, and swapExactTokensForETH. Each of these methods has different use cases.

A. swapExactETHForTokens: This function is used when you want to swap an exact amount of KLAY for as many output tokens as possible along the route determined by the path. Note that this function wraps your KLAY to WKLAY. 

struct SwapParams {
        address to;
        address[] path;
        address[] pool;
        uint deadline;
}
function swapExactETHForTokens(
        uint256 amountOutMin, 
        SwapParams calldata p
) external payable returns (uint256[] memory amounts);

B. swapExactTokensForTokens: This function is used when you want to swap an exact amount of input tokens for as many output tokens as possible along the route determined by the path. The first path element is the input token, and the last is the output token.

struct SwapParams {
        address to;
        address[] path;
        address[] pool;
        uint deadline;
}
   function swapExactTokensForTokens(
        uint256 amountIn, 
        uint256 amountOutMin, 
        SwapParams calldata params
    ) external returns (uint256[] memory amounts);

C. swapExactTokensForETH: This function is used when you want to swap an exact amount of tokens for as much ETH as possible, along the route determined by the path. The first path element is the input token, the last must be WKLAY.  

struct SwapParams {
        address to;
        address[] path;
        address[] pool;
        uint deadline;
}
    function swapExactTokensForETH(
        uint256 amountIn, 
        uint256 amountOutMin, 
        SwapParams calldata p
    ) external returns (uint256[] memory amounts);

For an in-depth description of each of the parameters for this function, check out the KLAYswap UniversalRouter Parameter Structs

Fully working example

Here’s a fully working example you can use directly for your swap operations. It allows you to trade KLAY for sKAI, sKAI to KLAY and also swap any tokens to tokens. 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
 interface IKlaySwapRouterV2  {
    struct SwapParams {
        address to;
        address[] path;
        address[] pool;
        uint deadline;
    }
    function swapExactTokensForTokens(
        uint256 amountIn, 
        uint256 amountOutMin, 
        SwapParams calldata params
    ) external returns (uint256[] memory amounts);
    function swapExactETHForTokens(
        uint256 amountOutMin, 
        SwapParams calldata p
    ) external payable returns (uint256[] memory amounts);
    function swapExactTokensForETH(
        uint256 amountIn, 
        uint256 amountOutMin, 
        SwapParams calldata p
    ) external returns (uint256[] memory amounts);
}
interface IERC20 {
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
}
contract MiniKLAYSwap {
    address public constant routerAddress = 0xe0fbB27D0E7F3a397A67a9d4864D4f4DD7cF8cB9;
    address public constant MBX_TOKEN_ADDRESS = 0xD068c52d81f4409B9502dA926aCE3301cc41f623;
    address public constant sKAI_TOKEN_ADDRESS = 0x37d46C6813B121d6A27eD263AeF782081ae95434;
    address public constant WKLAY_ADDRESS = 0x19Aac5f612f524B754CA7e7c41cbFa2E981A4432;
    IKlaySwapRouterV2 public immutable swapRouter = IKlaySwapRouterV2(routerAddress);
    IERC20 public immutable MBX_TOKEN = IERC20(MBX_TOKEN_ADDRESS);
    IERC20 public immutable SKAI_TOKEN = IERC20(sKAI_TOKEN_ADDRESS);    
    address[] private pool =  [address(0)];
    address[] private path =  [MBX_TOKEN_ADDRESS, WKLAY_ADDRESS];
    address[] private path1 =  [WKLAY_ADDRESS, sKAI_TOKEN_ADDRESS];
    address[] private path2 =  [sKAI_TOKEN_ADDRESS, WKLAY_ADDRESS];
    // must give contract ownership of input token
    // approve this contract address(this) of amount in; 
    // this approval enables the transfer of input token to this contract: address(this)
    function swapExactTokensForTokens(uint256 amountIn)
        external
        returns (uint256[] memory amountOut)
    {
        MBX_TOKEN.transferFrom(msg.sender, address(this), amountIn);
        MBX_TOKEN.approve(address(swapRouter), amountIn);
        IKlaySwapRouterV2.SwapParams memory params = IKlaySwapRouterV2
            .SwapParams({
                to: msg.sender,
                path: path,
                pool: pool,
                deadline: block.timestamp        
            });
        amountOut = swapRouter.swapExactTokensForTokens(amountIn, 1, params);
    }
    function swapExactKLAYForTokens()
                external
                payable 
                returns (uint256[] memory amountOut)
            {
            IKlaySwapRouterV2.SwapParams memory params = IKlaySwapRouterV2
                .SwapParams({
                    to: msg.sender,
                    path: path1,
                    pool: pool,
                    deadline: block.timestamp        
                });
            amountOut = swapRouter.swapExactETHForTokens{value: msg.value}(1, params);
    }
    // must give contract ownership of input token
    // approve this contract address(this) of amount in; 
    // this approval enables the transfer of input token to address(this)
    function swapExactTokensForKLAY(uint256 amountIn)
                external 
                returns (uint256[] memory amountOut)
            {
            
            SKAI_TOKEN.transferFrom(msg.sender, address(this), amountIn);
            SKAI_TOKEN.approve(address(swapRouter), amountIn);
            IKlaySwapRouterV2.SwapParams memory params = IKlaySwapRouterV2
                .SwapParams({
                    to: msg.sender,
                    path: path2,
                    pool: pool,
                    deadline: block.timestamp        
                });
            amountOut = swapRouter.swapExactTokensForETH(amountIn, 1, params);
    }
}

You can get the full source code above on Github

Deploying MiniKLAYswap.sol using thirdweb CLI

To deploy the MiniKLAYswap.sol using the thirdweb CLI, take a look at this guide. After following the steps in the deployment guide, ensure to:

i. Give your project a name.
ii. Choose your preferred framework: Hardhat or Foundry.
iii. Name your smart contract for example MiniKLAYswap.sol
iv. Choose the type of base contract: Empty, ERC20, ERC721, or ERC1155. Add any desired extensions. For this tutorial, you will select the Empty option.
v. Paste the code above in your newly created file: MiniKLAYswap.sol
vi. Deploy contract using the `npx thirdweb deploy` command 

Performing the Swap operation

In this section, we will perform the swap operation by calling the swapExactKLAYForTokens and swapExactTokensForKLAY methods using the thirdweb dashboard. 

*Note: If the token you want to swap has no liquidity, a pair with liquidity must be created before you can swap. It is safe to perform a KLAY/sKAI swap because a liquidity pool exists. 

Lets go over the swap execution one after the other:

1. swapExactKLAYForTokens. 

To swap exact KLAY for tokens, follow the steps below:

i. Navigate to the explorer tab of your deployed MiniKLAYswap contract on Thirdweb’s dashboard
ii. Click on the swapExactKLAYforTokens method in the contract write tab.
iii. Input the amount of KLAY to be swapped in the input field provided. 
iv. Click the Execute button to perform the swap operation.

Once the swap has been completed, you should see your transaction hash in the output field below:

To verify the swap operation, paste your swap transaction hash in the search bar of Klaytnscope as seen below: 

2. swapExactTokensForKLAY. 

Now let’s swap back our tokens to exact KLAY. To do this, follow the steps below:

A.  Approve the MiniKLAYswap contract the amount of tokens you wish to swap. 

This is so because you want the MiniKLAYswap contract to be in control of the tokens (sKAI in this example). To do this, follow the steps below:

i. Navigate to the sKAI contract tab on Klaytnscope. 

ii. Connect your metamask wallet in order to execute the approve method
iii. Click on the approve method
iv. Paste the MiniKLAYswap Contract address and amount of tokens to be swapped in the spender  and amount input field respectively 
v. Click on the Write button to execute the approve method. 

*Note: We interacted with the sKAI token contract directly from Klaytnscope because it is a verified contract. 

B. Execute the Swap operation

Now that we have approved the MiniKLAYswap to be in control of the sKAI tokens, we can now perform the swap operation. To do this, follow the steps below:

i. Navigate to the explorer tab of your deployed MiniKLAYswap contract on Thirdweb’s dashboard 
ii. Click on the swapExactTokensForKLAY method in the contract write tab.
iii. Input the amount of tokens to be swapped in the input field provided.
iv. Click the Execute button to perform the swap operation.

Once the swap has been completed, you should see your transaction hash in the output field like this below:

To verify the swap operation, paste your swap transaction hash in the search bar of Klaytnscope as seen below: 

Conclusion

Kudos! You now have a better understanding of KLAYswap and how to integrate it programmatically into your smart contract. So far, this tutorial demonstrated how to implement the swap method available using the KLAYswap Universal Router and as a result we were able to swap KLAY to sKAI and vice versa.  in Part 2, you will learn how to build a minimalistic frontend that interacts with the MiniKLAYswap contract using thirdweb and Next.js. If you want more information, visit Klaytn Docs and KLAYswap Docs. If you have any questions, visit Klaytn Forum.