3

I got this error when tried to deposit eth to weth contact from mainnet, using hardhat forking, does anyone know how to fix this error ?

const { getNamedAccounts, ethers, } = require("hardhat")

const AMOUNT = ethers.parseEther("0.02")

async function getWeth() {
    const { deployer } = await getNamedAccounts()
    const iWeth = await ethers.getContractAt(
        "IWeth",
        "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
        deployer,
    )
    const tx = await iWeth.deposit({ value: AMOUNT })
    await tx.wait(1)
    const wethBalance = await iWeth.balanceOf(deployer)
    console.log(`Got ${wethBalance.toString()} WETH`)
}

module.exports = { getWeth }

I console.log contract got from getContractAt(), It's shown like this, please help

Contract {
  target: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
  interface: Interface {
    fragments: [
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment],
      [FunctionFragment]
    ],
    deploy: ConstructorFragment {
      type: 'constructor',
      inputs: [],
      payable: false,
      gas: null
    },
    fallback: null,
    receive: false
  },
  runner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
  filters: {},
  fallback: null,
  [Symbol(_ethersInternal_contract)]: {}
}
/home/sonhd/blockchain/hardhat-defi-fcc/node_modules/ethers/src.ts/utils/errors.ts:677
            error = new Error(message);
                    ^
Error: contract runner does not support sending transactions (operation="sendTransaction", code=UNSUPPORTED_OPERATION, version=6.6.4)
    at makeError (.../hardhat-defi-fcc/node_modules/ethers/src.ts/utils/errors.ts:677:21)
    at assert (.../hardhat-defi-fcc/node_modules/ethers/src.ts/utils/errors.ts:694:25)
    at send (.../hardhat-defi-fcc/node_modules/ethers/src.ts/contract/contract.ts:288:15)
    at Proxy.deposit (.../hardhat-defi-fcc/node_modules/ethers/src.ts/contract/contract.ts:330:22)
    at getWeth (.../hardhat-defi-fcc/scripts/getWeth.js:13:28)
    at main (.../hardhat-defi-fcc/scripts/aaveBorrow.js:3:2)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Hardhat package.json config

{
  "devDependencies": {
    "@chainlink/contracts": "^0.6.1",
    "@nomicfoundation/hardhat-ethers": "^3.0.4",
    "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
    "@nomiclabs/hardhat-etherscan": "^3.1.7",
    "@nomiclabs/hardhat-waffle": "^2.0.6",
    "chai": "^4.3.7",
    "dotenv": "^16.3.1",
    "ethereum-waffle": "^4.0.10",
    "ethers": "^6.6.4",
    "hardhat": "^2.17.0",
    "hardhat-contract-sizer": "^2.10.0",
    "hardhat-deploy": "^0.11.34",
    "hardhat-gas-reporter": "^1.0.9",
    "prettier": "^3.0.0",
    "prettier-plugin-solidity": "^1.1.3",
    "solhint": "^3.4.1",
    "solidity-coverage": "^0.8.4"
  },
  "dependencies": {}
}

And the contract could be found at hardhat-defi-fcc/tree/main/contracts/interfaces

5 Answers 5

3

You just need to get a signer by const signer = await ethers.provider.getSigner() and then, pass this signer to sign transaction in the ethers.getContractAt() function rather than deployer in your case.

Also remember, just use ethers.parseEther("0.02") with updated versions of ethers rather than "ethers.utils.parseEther("0.02")".

const { getNamedAccounts, ethers } = require("hardhat")

const AMOUNT = ethers.parseEther("0.02")

async function getWeth() {
   const { deployer } = await getNamedAccounts()

   const signer = await ethers.provider.getSigner()

   const iWeth = await ethers.getContractAt(
       "IWeth",
       "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
       signer,
   )

   const tx = await iWeth.deposit({ value: AMOUNT })
   await tx.wait(1)
   const wethBalance = await iWeth.balanceOf(deployer)
   console.log(`Got ${wethBalance.toString()} WETH.`)
}

module.exports = { getWeth }

2

Okay, I found a solution that worked based on Malik's answer

In summary, we need a signer to change the state of the contract (as we are using the deposit() function). To achieve this, I used ethers.provider.getSigner().

I also used getTheAbi() to obtain the ABI of the contract.

I believe there might be a better way to get the abi because we already have contract by using ethers.getContractAt(), but I don't know. Hopefully, someone can provide a more efficient approach."

const fs = require("fs")
const path = require("path")

const getTheAbi = () => {
    try {
        const dir = path.resolve(
            __dirname,
            "../artifacts/contracts/interfaces/IWeth.sol/IWeth.json", // hardhat build dir
        )
        const file = fs.readFileSync(dir, "utf8")
        const json = JSON.parse(file)
        return json.abi

    } catch (e) {
        console.log(`e`, e)
    }
}

const { getNamedAccounts, ethers } = require("hardhat")
const AMOUNT = ethers.parseEther("0.02")

async function getWeth() {
    const { deployer } = await getNamedAccounts()
    const abi = getTheAbi()
    const signer = await ethers.provider.getSigner()
    const newcontract = new ethers.Contract(
        "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
        abi,
        signer,
    )
    const tx = await newcontract.deposit({ value: AMOUNT })
    await tx.wait(1)
    const wethBalance = await newcontract.balanceOf(deployer)
    console.log(`Got ${wethBalance.toString()} WETH`)
}

module.exports = { getWeth }
2

Although slightly unrelated, I will leave my solution here for anyone who finds themselves here with a similar issue.

I was trying to use an Ethereum address in my connect function when I actually needed an ethers.signer object. Below is the incorrect code:

[deployer, recipient, ...otherAccounts] = await ethers.getSigners();
await token.connect(accounts[0].address).mint("1000000000000000000000");

and the correct code:

[deployer, recipient, ...otherAccounts] = await ethers.getSigners();
await token.connect(accounts[0]).mint("1000000000000000000000");```
0
const { ethers } = require("hardhat");
const { expect } = require("chai");


const contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";

describe("Access Storage Test", function () {
    
    // variables accessible throughout the test
    let contractInstance, signer1, signer1Address

    beforeEach("setup", async () => {
   
        // if hardhat or local dev is used leave it empty, but 
        // in hardhat.config
        provider = new ethers.JsonRpcProvider();

        // if a 3rd party service is used.
        provider = new ethers.JsonRpcProvider(`https://eth-sepolia.g.alchemy.com/v2/${process.env.ALCHEMY_SEPOLIA_API_KEY}`);

        signer1= new ethers.Wallet(process.env.PRIVATE_KEY_ONE, provider);
        signer1Address = await signer1.getAddress();

        const contractArtifact = await artifacts.readArtifact("contractName");
        const abi = contractArtifact .abi;
        try {
            contractInstance = new ethers.Contract(contractAddress, abi, provider);
        } catch (error) {
            console.error("Error creating contract instance:", error);
        }
})

desribe('whatever', function() {
it('execute deposit', async () => {
   const depositTx = await contractInstance.connect(signer1).deposit({value: ethers.parseEther("0.05")})
})

I believe this is a better way to get contract's abi and utilize different signers if needed as per ethers v6. I hope I helped a bit. Don't forget to set paths in hardhat.config.js:

paths: {
    sources: "./contracts", 
    artifacts: "./artifacts", 
    cache: "./cache"
  },

0

Dont forget to connect when you calling the contract

Not

const testFactory = await uniswapV2Factory.feeTo()

But

const testFactory = await uniswapV2Factory.connect(owner).feeTo()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.