I'm currently working on a project that involves creating two custom tokens on the Mumbai testnet and performing a swap operation for these tokens on Uniswap. However, I'm encountering an issue when trying to execute the trade.
I've already managed to create the tokens and the liquidity pool, but the trading operation fails. Here's my code:
const {
Pool,
Route,
SwapOptions,
FeeAmount,
computePoolAddress,
SwapQuoter,
SwapRouter,
Trade,
} = require("@uniswap/v3-sdk");
const {
Token,
CurrencyAmount,
TradeType,
Percent,
} = require("@uniswap/sdk-core");
const JSBI = require("jsbi");
const Quoter = require("@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json");
const IUniswapV3PoolABI = require("@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json");
const provider = new ethers.providers.JsonRpcProvider(
process.env.POLYGON_MUMBAI
);
const YING_TOKEN = new Token(80001, process.env.YING_ADDRESS, 18, "YING", "ying");
const YANG_TOKEN = new Token(80001, process.env.YANG_ADDRESS, 18, "YANG", "yang");
let Amount = "54321";
async function createTrade(){
const poolConstants = await getPoolConstants();
const pool = new Pool(
YING_TOKEN,
YANG_TOKEN,
FeeAmount.MEDIUM,
poolConstants.sqrtPriceX96.toString(),
poolConstants.liquidity.toString(),
poolConstants.tick
);
const swapRoute = new Route(
[pool],
YING_TOKEN,
YANG_TOKEN
);
const temp = await quote();
let amountOut = JSBI.BigInt(temp);
JSBI.toNumber(amountOut),JSBI.toNumber(amountOut))
let numAmt = JSBI.toNumber(amountOut);
const val = ethers.utils.parseUnits(Amount, YING_TOKEN.decimals);
const uncheckedTrade = Trade.createUncheckedTrade({
route: swapRoute,
inputAmount: CurrencyAmount.fromRawAmount(YING_TOKEN, val.toString()),
outputAmount: CurrencyAmount.fromRawAmount(
YANG_TOKEN,
numAmt
),
tradeType: TradeType.EXACT_INPUT,
});
return uncheckedTrade;
}
// Execute trade function...
async function executeTrade(trade){
// Give approval to the router to spend the token
const tokenApproval = await getTokenTransferApproval(
YING_TOKEN
);
if (tokenApproval == "no") return;
const options = {
slippageTolerance: new Percent(900, 1000),
deadline: Math.floor(Date.now() / 1000) + 60 * 20, // 20 minutes from the current Unix time
recipient: process.env.PUB_KEY,
};
const methodParameters = SwapRouter.swapCallParameters([trade], options);
const tx = {
data: methodParameters.calldata,
to: SWAP_ROUTER_ADDRESS,
value: methodParameters.value,
from: walletAddress,
maxFeePerGas: MAX_FEE_PER_GAS,
maxPriorityFeePerGas: MAX_PRIORITY_FEE_PER_GAS,
};
const res = await wallet.sendTransaction(tx);
return res;
}
async function quote() {
const poolConstants = await getPoolConstants();
const quoterContract = new ethers.Contract(
process.env.QUOTER_CONTRACT_ADDRESS,
Quoter.abi,
provider
);
const amountIn = ethers.utils.parseUnits(Amount, YING_TOKEN.decimals);
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
poolConstants.token0,
poolConstants.token1,
poolConstants.fee,
amountIn.toString(),
0
);
console.log("Pure quote : ",quotedAmountOut.toString());
return quotedAmountOut.toString();
}
async function getTokenTransferApproval(token){
try {
const inVal = ethers.utils.parseUnits(
TOKEN_AMOUNT_TO_APPROVE_FOR_TRANSFER,
token.decimals
);
const tokenContract = new ethers.Contract(
token.address,
ERC20_ABI,
provider
);
const transaction = await tokenContract.populateTransaction.approve(
process.env.uniSwapUniversal,
inVal.toString()
);
const txRes = await wallet.sendTransaction(transaction);
console.log(txRes);
return "yes"
} catch (e) {
return "no"
}
}
async function getPoolConstants() {
const currentPoolAddress = process.env.YING_YANG_POOL;
// console.log("Current Pool Address : ",currentPoolAddress);
const poolContract = new ethers.Contract(
currentPoolAddress,
IUniswapV3PoolABI.abi,
provider
);
const [token0, token1, fee, tickSpacing, liquidity, slot0] =
await Promise.all([
poolContract.token0(),
poolContract.token1(),
poolContract.fee(),
poolContract.tickSpacing(),
poolContract.liquidity(),
poolContract.slot0(),
]);
return {
token0,
token1,
fee,
tickSpacing,
liquidity,
sqrtPriceX96: slot0[0],
tick: slot0[1],
};
}
async function main(){
const trade = await createTrade()
const res = executeTrade(trade);
console.log(res);
}
main();
module.exports = { quote, createTrade,executeTrade };
Error I Got:
D:\trading bot\0xArbi-bot\node_modules\@uniswap\sdk-core\dist\sdk-core.cjs.development.js:82
throw new Error('Could not parse fraction');
^
Error: Could not parse fraction
at Function.tryParseFraction (D:\trading bot\0xArbi-bot\node_modules\@uniswap\sdk-core\dist\sdk-core.cjs.development.js:82:11)
at Percent.lessThan (D:\trading bot\0xArbi-bot\node_modules\@uniswap\sdk-core\dist\sdk-core.cjs.development.js:113:32)
at Trade.minimumAmountOut (D:\trading bot\0xArbi-bot\node_modules\@uniswap\v3-sdk\dist\v3-sdk.cjs.development.js:3027:25)
at D:\trading bot\0xArbi-bot\node_modules\@uniswap\v3-sdk\dist\v3-sdk.cjs.development.js:3977:28
at Array.reduce (<anonymous>)
at Function.swapCallParameters (D:\trading bot\0xArbi-bot\node_modules\@uniswap\v3-sdk\dist\v3-sdk.cjs.development.js:3976:33)
at executeTrade (D:\trading bot\0xArbi-bot\uniswapCustom.js:143:40)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Error Point:
const methodParameters = SwapRouter.swapCallParameters([trade], options);
I tried all possible formats to send the amountOut (numAmt) while creating unckecked trade but nothing changes.