Liquidity pools

How to swap security tokens

To Buy/Sell security tokens, Edit/Cancel orders and Settle trades on Verified Network, user needs to call swap or batchSwap function on Verified Pool contract. The "userData" , "asset in", "asset out" arguments passed to either swap or batchSwap determine the type of swap.

For Buying or Selling of Security Tokens: Asset in is either Currency token address for Buy orders or Security token address for Sell orders. Asset out is Pool address(VPT token address of the pool) for both.

/** Import Pool contract and ethers **/

//Common Js
const { Pool } = require('@verified-network/verified-sdk'); 
const { ethers } = require('ethers');
//ES Module
import { Pool } from '@verified-network/verified-sdk'
import { ethers } from 'ethers';

/** Initialize Pool Contract and abi encoder**/
    const providerOrSigner = 'provider or signer'  //can be investorWalletProvider from Wallet and Contracts page or Signer from web wallets
    const poolContract = new Pool(providerOrSigner);
    const abiCoder = new ethers.utils.AbiCoder();

/** Format Swap Arguments **/
 //Argument 1: Swap
    const swapType = 'Market or Limit' //type of swap
    const poolId = 'id of pool to swap from in bytes' //e.g 0x1c54eb0a8bea5eeaf07b1b6d2238baf4bf6d6a4800000000000000000000009a
    const swapKind = 'number 0 or 1' //SwapExactIn = 0 or SwapExactOun = 1;
    const assetIn = 'address of token to swap in(token from)' //when security address is token in it means Sell order, when currency address is token in it means Buy order
    const assetOut = 'address of token out' //same as poolAddress(VPT token) e.g 0x1c54eb0a8BEa5eEaf07b1b6d2238BAf4BF6D6a48
    const amount = 'number(amount) of token in' //must be in same decimal places with token in.
    let userData;
    //There are 2 types of swap.
    // 1. Market: swap without price will be traded at current market price.
    if(swapType === "Market") {
        userData = "0x" //null abi encoded parameter of [bytes32, uint]
        //same as abiCoder.encode(["bytes32", "uint"],[]);
    }
    // 2. Limit: swap with price, will be traded at price specified.
    if(swapType === "Limit") {
        const priceWei = 'number(amount) of price in wei'
        userData = abiCoder.encode(
          ["bytes32", "uint256"],
          [ethers.utils.formatBytes32String("Limit"), priceWei]
        );
    }
    //This type of swap with 'kind' works for swap, for batchSwap it does not have 'kind'.
     const swap = {
         poolId: poolId,
         kind: swapKind,
         assetIn: assetIn,
         assetOut: assetOut,
         amount: amount,
         userData: userData
     }
 //Argument 2: Funds
    const funds = {
        sender: 'investor/sender address', //address of swap sender
        fromInternalBalance: false, //boolean must be false not to use internal balance
        recipient: 'investor/sender address', //address of swap receiver
        toInternalBalance: false, //boolean must be false not to use internal balance
     }
 //Argument 3: limit
     const limit = 'number of amountIn limit' //e.g 0 or amount of token in
 //Argument 4: Deadline
     const deadline = 'number deadline of transaction' //e.g 999999999999999999(infinity) or very high number
     
/** Call swap or batchSwap on Pool contract **/
    //Swap: for single swap
    await poolContract.swap(swap, funds, limit, deadline).then((res) => {
        const swapResponse = res.response;
        if(swapResponse.status === 0) { 
            //status 0 means succesful transaction
            console.log("swap successful with transaction hash: ", swapResponse.hash)
        }else{
            //status 1 means failed transaction
            console.error("Unexpected error occured while calling swap function with message: ", swapResponse.message || swapResponse.reason)
        }
    }).catch((err) => {
        console.error("Swap failed with error: ", err)
    })
    
    //batchSwap: single and multiple swaps. cost less gas
    //call getPoolTokens to get pool tokens list.
    const poolTokensResponse = await poolContract.getPoolTokens(poolId);
    const assests = poolTokensResponse.response.result; //array of tokens address(includes security, currency and pool addrress)
    const assetInIndex = assests.findIndex((tkn) => {
        return tkn.toLowerCase() === assetIn.toLowerCase();
    });//batchswap takes assetInindex(index of tokenIn in assests array) unlike swap with assetIn(address of token in)
    const assetOutIndex = poolTokens.tokens.findIndex((tkn) => {
    return tkn.toLowerCase() === assetOut.toLowerCase();
    });//batchswap takes assetOutindex(index of token out in assests array) unlike swap with assetOut(address of token out)
    let limits = new Array(3).fill(0); //batchswap takes limits in array of numbers unlike swap with limit as number
    limits[assetInIndex] = amount; //update the limit for index of token in.
    let batchSwap = {
        poolId: poolId, //the same with poolId above
        assetInIndex: assetInIndex,
        assetOutIndex: assetOutIndex,
        amount: amount, //the same with amount above.
        userData: userData //the same with userData above
    } //does not have 'kind' like swap argument
    
    const swaps = [batchSwap] //batchSwap takes swaps in array. add more swap for multiple swaps
    await poolContract.batchswap(swapKind, swaps, assests, funds, limits, deadline).then((res) => {
        const batchSwapResponse = res.response;
        if(batchSwapResponse.status === 0) {
             //status 0 means succesful transaction
            console.log("batchswap successful with transaction hash: ", batchSwapResponse.hash)
        }else{
            //status 1 means failed transaction
            console.error("Unexpected error occured while calling batchswap function with message: ", batchSwapResponse.message || batchSwapResponse.reason)
        }
    }).catch((err) => {
        console.error("Batchswap failed with error: ", err)
    }

For Cancel/Edit Orders: Asset in is Pool address(VPT token address of the pool) for Cancel order or Currency/Security token address for Edit order. Asset out is Security/Currency token address for Cancel Order or Pool address(VPT token address of the pool) for Edit order.

/** Import Pool contract and ethers **/

//Common Js
const { Pool } = require('@verified-network/verified-sdk'); 
const { ethers } = require('ethers');
//ES Module
import { Pool } from '@verified-network/verified-sdk'
import { ethers } from 'ethers';

/** Initialize Pool Contract and abi encoder**/
    const providerOrSigner = 'provider or signer'  //can be investorWalletProvider from Wallet and Contracts page or Signer from web wallets
    const poolContract = new Pool(providerOrSigner);
    const abiCoder = new ethers.utils.AbiCoder();

/** Format Swap Arguments **/
 //Argument 1: Swap
    const poolId = 'id of pool in bytes' //e.g 0x1c54eb0a8bea5eeaf07b1b6d2238baf4bf6d6a4800000000000000000000009a
    const swapKind = 'number 0 or 1' //SwapExactIn = 0 or SwapExactOun = 1;
    const assetIn = 'address of token to swap in(token from)' // pool address for cancel order, security/currency address for edit order
    const assetOut = 'address of token out' // security/currency address for cancel order. pool address for edit  order
    const amount = 'number(amount) of token in' //must be in same decimal places with token in.
    const orderReference = 'order reference of order to cancel or edit in bytes32'
    const price = 'number(amount) of new price' //0 for cancel order
    //for cancel order
    const userData = abiCoder.encode(
      ["bytes32", "uint256"],
      [orderReference, 0]
    );
    //for edit order
    const userData = abiCoder.encode(
      ["bytes32", "uint256"],
      [orderReference, price]
    );
    //This type of swap with 'kind' works for swap, for batchSwap it does not have 'kind'.
     const swap = {
         poolId: poolId,
         kind: swapKind,
         assetIn: assetIn,
         assetOut: assetOut,
         amount: amount,
         userData: userData
     }
 //Argument 2: Funds
    const funds = {
        sender: 'investor/sender address', //address of swap sender
        fromInternalBalance: false, //boolean must be false not to use internal balance
        recipient: 'investor/sender address', //address of swap receiver
        toInternalBalance: false, //boolean must be false not to use internal balance
     }
 //Argument 3: limit
     const limit = 'number of amountIn limit' //e.g 0 or amount of token in
 //Argument 4: Deadline
     const deadline = 'number deadline of transaction' //e.g 999999999999999999(infinity) or very high number
     
/** Call swap or batchSwap on Pool contract **/
    //Swap: for single swap
    await poolContract.swap(swap, funds, limit, deadline).then((res) => {
        const swapResponse = res.response;
        if(swapResponse.status === 0) { 
            //status 0 means succesful transaction
            console.log("swap successful with transaction hash: ", swapResponse.hash)
        }else{
            //status 1 means failed transaction
            console.error("Unexpected error occured while calling swap function with message: ", swapResponse.message || swapResponse.reason)
        }
    }).catch((err) => {
        console.error("Swap failed with error: ", err)
    })
    
    //batchSwap: single and multiple swaps. cost less gas
    //call getPoolTokens to get pool tokens list.
    const poolTokensResponse = await poolContract.getPoolTokens(poolId);
    const assests = poolTokensResponse.response.result; //array of tokens address(includes security, currency and pool addrress)
    const assetInIndex = assests.findIndex((tkn) => {
        return tkn.toLowerCase() === assetIn.toLowerCase();
    });//batchswap takes assetInindex(index of tokenIn in assests array) unlike swap with assetIn(address of token in)
    const assetOutIndex = poolTokens.tokens.findIndex((tkn) => {
    return tkn.toLowerCase() === assetOut.toLowerCase();
    });//batchswap takes assetOutindex(index of token out in assests array) unlike swap with assetOut(address of token out)
    let limits = new Array(3).fill(0); //batchswap takes limits in array of numbers unlike swap with limit as number
    limits[assetInIndex] = amount; //update the limit for index of token in.
    let batchSwap = {
        poolId: poolId,
        assetInIndex: assetInIndex,
        assetOutIndex: assetOutIndex,
        amount: amount, //the same with amount above.
        userData: userData //the same with userData above
    } //does not have 'kind' like swap argument
    const swaps = [batchSwap] //batchSwap takes swaps in array. add more swap for multiple swaps
    await poolContract.batchswap(swapKind, swaps, assests, funds, limits, deadline).then((res) => {
        const batchSwapResponse = res.response;
        if(batchSwapResponse.status === 0) {
             //status 0 means succesful transaction
            console.log("batchswap successful with transaction hash: ", batchSwapResponse.hash)
        }else{
            //status 1 means failed transaction
            console.error("Unexpected error occured while calling batchswap function with message: ", batchSwapResponse.message || batchSwapResponse.reason)
        }
    }).catch((err) => {
        console.error("Batchswap failed with error: ", err)
    }

To Settle trades: Asset in is Pool address(VPT token address of the pool). Asset out is either Security token address for Buy orders or Currency token address for Sell orders.

/** Import Pool contract and ethers **/

//Common Js
const { Pool } = require('@verified-network/verified-sdk'); 
const { ethers } = require('ethers');
//ES Module
import { Pool } from '@verified-network/verified-sdk'
import { ethers } from 'ethers';

/** Initialize Pool Contract and abi encoder**/
    const providerOrSigner = 'provider or signer'  //can be investorWalletProvider from Wallet and Contracts page or Signer from web wallets
    const poolContract = new Pool(providerOrSigner);
    const abiCoder = new ethers.utils.AbiCoder();

/** Format Swap Arguments **/
 //Argument 1: Swap
    const poolId = 'id of pool in bytes' //e.g 0x1c54eb0a8bea5eeaf07b1b6d2238baf4bf6d6a4800000000000000000000009a
    const swapKind = 'number 0 or 1' //SwapExactIn = 0 or SwapExactOun = 1;
    const assetIn = 'address of token to swap in(token from)' // pool address(vpt token address of the pool)
    const assetOut = 'address of token out' // security address for buy orders and currency address for sell orders
    const amount = 'number(amount) to settle' //must be in same decimal places with token in.
    const tradeTime = 'number(timestamp) of trade' //time trade to settle was created
    const userData = abiCoder.encode(
      ["bytes32", "uint256"],
      [ethers.utils.formatBytes32String(""), tradeTime]
    );
    //This type of swap with 'kind' works for swap, for batchSwap it does not have 'kind'.
     const swap = {
         poolId: poolId,
         kind: swapKind,
         assetIn: assetIn,
         assetOut: assetOut,
         amount: amount,
         userData: userData
     }
 //Argument 2: Funds
    const funds = {
        sender: 'investor/sender address', //address of swap sender
        fromInternalBalance: false, //boolean must be false not to use internal balance
        recipient: 'investor/sender address', //address of swap receiver
        toInternalBalance: false, //boolean must be false not to use internal balance
     }
 //Argument 3: limit
     const limit = 'number of amountIn limit' //e.g 0 or amount of token in
 //Argument 4: Deadline
     const deadline = 'number deadline of transaction' //e.g 999999999999999999(infinity) or very high number
     
/** Call swap or batchSwap on Pool contract **/
    //Swap: for single swap
    await poolContract.swap(swap, funds, limit, deadline).then((res) => {
        const swapResponse = res.response;
        if(swapResponse.status === 0) { 
            //status 0 means succesful transaction
            console.log("Settle trade successful with transaction hash: ", swapResponse.hash)
        }else{
            //status 1 means failed transaction
            console.error("Unexpected error occured while settling trade with message: ", swapResponse.message || swapResponse.reason)
        }
    }).catch((err) => {
        console.error("Settle trade failed with error: ", err)
    })
    
    //batchSwap: single and multiple swaps. cost less gas
    //call getPoolTokens to get pool tokens list.
    const poolTokensResponse = await poolContract.getPoolTokens(poolId);
    const assests = poolTokensResponse.response.result; //array of tokens address(includes security, currency and pool addrress)
    const assetInIndex = assests.findIndex((tkn) => {
        return tkn.toLowerCase() === assetIn.toLowerCase();
    });//batchswap takes assetInindex(index of tokenIn in assests array) unlike swap with assetIn(address of token in)
    const assetOutIndex = poolTokens.tokens.findIndex((tkn) => {
    return tkn.toLowerCase() === assetOut.toLowerCase();
    });//batchswap takes assetOutindex(index of token out in assests array) unlike swap with assetOut(address of token out)
    let limits = new Array(3).fill(0); //batchswap takes limits in array of numbers unlike swap with limit as number
    limits[assetInIndex] = amount; //update the limit for index of token in.
    let batchSwap = {
        poolId: poolId,
        assetInIndex: assetInIndex,
        assetOutIndex: assetOutIndex,
        amount: amount, //the same with amount above.
        userData: userData //the same with userData above
    } //does not have 'kind' like swap argument
    const swaps = [batchSwap] //batchSwap takes swaps in array. add more swap for multiple swaps
    await poolContract.batchswap(swapKind, swaps, assests, funds, limits, deadline).then((res) => {
        const batchSwapResponse = res.response;
        if(batchSwapResponse.status === 0) {
             //status 0 means succesful transaction
            console.log("settle trade successful with transaction hash: ", batchSwapResponse.hash)
        }else{
            //status 1 means failed transaction
            console.error("Unexpected error occured while settling trade with message: ", batchSwapResponse.message || batchSwapResponse.reason)
        }
    }).catch((err) => {
        console.error("Settle trade failed with error: ", err)
    }

Last updated