Execute A Trade

KyberSwap Elastic Security Incident

On 22 Nov 2023, the Elastic protocol experienced a security incident. More details can be found via our official channels.

All other KyberSwap products (Aggregator, Limit Order, & Classic) continue to be fully operational.

Introduction

Optimized rates via the KyberSwap Aggregator

Note that the following demo routes trades via a specific Elastic pool. As such, the trade will be executed based on the pool price which can and will likely deviate from the market price.

For more optimized trade routes, please use our KyberSwap Aggregator API which scans multiple DEXs and pools for superior rates. This guide is meant for developers who would like to programmatically execute a trade against an Elastic pool.

This guide builds upon the quote that was obtained from the Get A Quote sample. To execute the swap via the Elastic Router contract, we will first need to construct the trade call using the returned quote parameters. Additionally, the Router contract must also be able to spend the specified amount of input tokens from the owner's wallet hence requiring approval (ERC20 Approve) to be provided.

The logic for executing a trade can be found in the trade.ts file linked below:

Signer configuration

In order to sign the transaction to be processed by the network, this example requires an Ethers Signer to be configured. Please view Provider and Signer Setup for more information.

Flow

Executing A Swap

Step 1: Approve Router contract spending

In order to execute the trade, the Router contract must have the necessary allowance to spend the specified tokens from the signer's address. We first query the token contract to check the existing Route contract allowance:

const contractAllowance = await token0Contract.allowance(signerAddress, elasticContracts.ROUTER);

If the Router contract allowance is insufficient, we will sign an approve transaction for the exact amount of input tokens required for the trade. This is executed via the getTokenApproval() function which:

const approvalTx = await token0Contract.approve(
    elasticContracts.ROUTER, 
    BigInt(inputAmount.quotient.toString()), 
    {maxFeePerGas: 100000000000, maxPriorityFeePerGas: 100000000000}
    );
  • Waits for the Approve transaction to be executed

const approvalTxReceipt = await approvalTx.wait();
  • Queries the new Router allowance for confirmation

const newContractAllowance = await token0Contract.allowance(signerAddress, elasticContracts.ROUTER)

A transaction hash will be returned upon successful approval:

Step 2: Create unchecked trade and configure swap options

Once we have the required allowance, we can then start to construct the trade. We first create an unchecked trade using the returned route:

const tradeConstructorArgs = {
    route,
    inputAmount,
    outputAmount,
    tradeType
};
const uncheckedTrade = Trade.createUncheckedTrade(tradeConstructorArgs);

Note that createUncheckedTrade() does not validate the result of swapping through the route and is meant to be used when trade simulation has been done elsewhere. In our case, we have already queried the Quoter contract.

In addition to the trade inputs, we will also need to configure the swap options:

const swapOptions: SwapOptions = {
    slippageTolerance: new Percent(500, 10000), // 50bips or 0.50%
    deadline: Math.floor(Date.now() / 1000) + 60 * 10, //10 mins
    recipient: signerAddress
};

Always remember to configure a slippageTolerance for your swap else risk your trade being front-run by bots via MEV.

Step 3: Get trade calldata from SwapRouter class

With the trade parameters in place, we can then use the SwapRouter class to generate the calldata required for the trade:

const swapMethodParams = SwapRouter.swapCallParameters([uncheckedTrade], swapOptions);

This will return the encoded calldata that will be sent to the network.

Step 4: Execute the swap

Real tokens involved

By executing the trade below, you will be trading tokens on your configured network. In this case, this example is trading tokens on Polygon PoS (ChainId: 137) which have a corresponding monetary value.

Please refer to Provider And Signer Setup for more info.

Finally, we can execute the trade by sending the transaction to the network with our Signer instance:

const swapTx = await getSigner().sendTransaction({
    data: swapMethodParams.calldata,
    to: elasticContracts.ROUTER,
    value: swapMethodParams.value,
    from: signerAddress,
    maxFeePerGas: 100000000000,
    maxPriorityFeePerGas: 100000000000
});

A transaction hash will be returned once the trade has been executed. You can copy this hash into a scanner (i.e. PolygonScan) and see that your transaction has been successfully completed by the network.

Last updated