How to buy with ethers js using Uniswap Universal router on Base? calling execute function

255 Views Asked by At

I want to buy new tokens launched on base using Uniswap Universal router on Base with node js and ether js libraries. Im calling execute function but I'm having many problems.

Here is the code:

`
const {ethers} = require("ethers")

const AbiCoder = new ethers.utils.AbiCoder()

// const tokenToBuy = '0xe67aB9Efb46d987d2aF816597F6716069A8a7426' //KIF

//Router
const routerAddress = '0x198EF79F1F515F02dFE9e3115eD9fC07183f02fC' // router
const file = fs.readFileSync("./B_Base/ABIUniversal.json", 'utf8') // Calls sushi ABI
const routerAbi = JSON.parse(file)
const routerContract = new ethers.Contract(routerAddress, routerAbi, signer)

// token input
const prompt = ps()
const tokenToBuy = String(prompt("Enter token name: ")) 

//wbnb to spend
const spend = ethers.utils.parseEther("0.0001")

const commands = 0x00

const path = [AbiCoder.encode(WETH), AbiCoder.encode(5000), AbiCoder.encode(tokenToBuy)]

 // Encode the parameters
const inputs = AbiCoder.encode(WALLET_ADDRESS, spend, 0, path, false)

const buy = async () => { // .execute execute(bytes commands,bytes[] inputs,uint256 deadline)
    const buy = await routerContract.execute(
      commands,
      inputs,
      Date.now() + 1000 * 60 * 10)
      
    receipt = await buy.wait()
    transactionHash = receipt.transactionHash
    console.log(transactionHash)
    
}


buy()`

There is an error when encoding the path and input to call the execute function. I don't understand the error is showing me I have been following ethers documentation and Uniswap docs too.

Error:

` if (types.length !== values.length) { ^

TypeError: Cannot read properties of undefined (reading 'length')
    at AbiCoder.encode (/home/oriok/DEV/degen/Arbitrum/node_modules/@ethersproject/abi/lib/abi-coder.js:82:37)
    at Object.<anonymous> (/home/oriok/DEV/degen/Arbitrum/B_Base/testinUni.js:52:24)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47`

What am I doing wrong? Is there any other router that allows you to buy any kind of token? I have been using SwapRouterV2 but doesnt allow me to buy some tokens. There aren't much solutions on Uniswap community discord either.

1

There are 1 best solutions below

2
signus On

Asked for version as there is a lot of overhaul from v5 to v6 of etherjs: refer to 5.7/packages/abi/lib/abi-coder.js for the changes.

It appears that the structure you're passing to encode when you're creating the path variable is where this is hitting because you should have a defined pair of types and values passed to the encode() function.

So where you pass the following:

const path = [AbiCoder.encode(WETH), AbiCoder.encode(5000), AbiCoder.encode(tokenToBuy)

Based on abi-coder.js(v5.7) it's looking that types and values match in pairs:

AbiCoder.prototype.encode = function (types, values) {
        var _this = this;
        if (types.length !== values.length) {
            logger.throwError("types/values length mismatch", logger_1.Logger.errors.INVALID_ARGUMENT, {
                count: { types: types.length, values: values.length },
                value: { types: types, values: values }
            });
        }

This should look a little more like:

const path = [
    AbiCoder.encode(["string"], [WETH]),
    AbiCoder.encode(["uint"], [5000]),
    AbiCoder.encode(["string"], [tokenToBuy])
]

So if you're only defining values and not predefining types for each value you would see that the amount of values (length) would not match the number of types in length either. Not providing the pair means that one would in fact be undefined.

However I would also revisit the reuse of encode on the following line - unsure how the ABI structure works with nested encoding.

I don't have intimate familiarity with etherjs, and am referring to structures available on the ethers AbiCoder documentation.