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