Token to Token PancakeSwap

 avatar
Mike112
typescript
7 months ago
4.8 kB
9
Indexable
Never
import { ethers } from "ethers";
import { Provider } from "zksync-web3";

// Providers for each chains

const zkSyncProvider = new Provider('https://mainnet.era.zksync.io');
const zkEvmProvider = new ethers.providers.JsonRpcProvider('https://zkevm-rpc.com');
const lineaProvider = new ethers.providers.JsonRpcProvider('https://rpc.linea.build');

// ABI for ERC20
const erc20ABI = [
    {
        "constant": false,
        "inputs": [
            { "name": "_spender", "type": "address" },
            { "name": "_value", "type": "uint256" }
        ],
        "name": "approve",
        "outputs": [{ "name": "", "type": "bool" }],
        "type": "function"
    }
];

// ABI for PancakeSwap Router
const routerABI = [
    'function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] path, address to, uint deadline) external returns (uint[] amounts)',
    'function swapExactETHForTokens(uint amountOutMin, address[] path, address to, uint deadline) external payable returns (uint[] amounts)',
    'function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] path, address to, uint deadline) external returns (uint[] amounts)'
];

// Router Address
const zkSyncRouter = "0x5aEaF2883FBf30f3D62471154eDa3C0c1b05942d";
const zkEvmRouter = "0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb";
const lineaRouter = "0x8cFe327CEc66d1C090Dd72bd0FF11d690C33a2Eb";

// Wrapped ETH Addresses for each chains

const zkSyncWETH = "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91";
const zkEvmWETH = "0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9";
const lineaWETH = "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f";

// Swap Function

async function swapTokens(
    chain: string,
    privateKey: string,
    fromToken: string,
    toToken: string,
    amount: string,
    recipient: string
): Promise<ethers.providers.TransactionReceipt> {

    let provider: ethers.providers.JsonRpcProvider;
    let wethAddress: string;
    let routerAddress: string;

    switch (chain) {
        case 'zkEvm':
            provider = zkEvmProvider;
            wethAddress = zkEvmWETH;
            routerAddress = zkEvmRouter;
            break;
        case 'zkSync':
            provider = zkSyncProvider;
            wethAddress = zkSyncWETH;
            routerAddress = zkSyncRouter;
            break;
        case 'linea':
            provider = lineaProvider;
            wethAddress = lineaWETH;
            routerAddress = lineaRouter;
            break;
        default:
            throw new Error('Unsupported Network');
    }

    const signer = new ethers.Wallet(privateKey, provider);

    // Get contract instance
    const router = new ethers.Contract(routerAddress, routerABI, signer);

    // Set deadline
    const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 minutes

    // Construct transaction
    if(fromToken === "ETH") {
        // ETH to Tokens
        const tx = await router.swapExactETHForTokens(
            0,
            [wethAddress, toToken],
            recipient,
            deadline,
        {
            value: amount
        });
        return await tx.wait();
    } else if(toToken === "ETH") {
        // Tokens to ETH

        // Approve token usage
        const tokenContract = new ethers.Contract(fromToken, erc20ABI, signer);

        let tx = await tokenContract.approve(routerAddress, amount);
        await tx.wait();

        tx = await router.swapExactTokensForTokens(
            amount,
            0,
            [fromToken, wethAddress],
            recipient,
            deadline
        );
        return await tx.wait();
    } else {
        // Tokens to Tokens
        let bestRoute: Array<string>;

        if(fromToken == wethAddress || toToken == wethAddress) {
            // Wrapped ETH <-> Tokens
            bestRoute = [fromToken, toToken];
        } else {
            // Multihop Swap Tokens
            bestRoute = [fromToken, wethAddress, toToken];
        }

        // Approve token usage
        const tokenContract = new ethers.Contract(fromToken, erc20ABI, signer);

        let tx = await tokenContract.approve(routerAddress, amount);
        await tx.wait();

        tx = await router.swapExactTokensForTokens(
            amount,
            0,
            bestRoute,
            recipient,
            deadline
        );
        return await tx.wait();
    }

}

// example usage:

// swapTokens('zkSync', '0x4cf1434ed89d5ca852e95db9b3d586603e6bab17b2eed581fe7ca186313c0ff0', '0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4', '0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91', '136799694', '0x6516A658698b0EF490c3959546a14069b7831A89')