Unable to pass a contract to revertedWithCustomError using viem and hardhat

86 views Asked by At

Using hardhat and viem, I am trying to test that a Solidity contract reverts with a Custom Error.

Context

The problem is with the first parameter of revertWithCustomError: the contract. I am unable to supply a value that comes from viem there. I am trying to use it like this:

await expect(
  contract.write.withdraw([BigInt(0)], {
    account: other.account,
  })
).to.be.revertedWithCustomError(
  contract
  "Unauthorized"
);

Attempts

With deployContract

const deployedContract = await hre.viem.deployContract("Inheritance");

With error:

Argument of type '{ read: { heir: (options?: { account?: `0x${string}` | Account | undefined; blockNumber?: bigint | undefined; blockTag?: BlockTag | undefined; } | undefined) => Promise<`0x${string}`>; lastWithdrawalAt: (options?: { ...; } | undefined) => Promise<...>; owner: (options?: { ...; } | undefined) => Promise<...>; }; esti...' is not assignable to parameter of type '{ interface: any; }'.
     Property 'interface' is missing in type '{ read: { heir: (options?: { account?: `0x${string}` | Account | undefined; blockNumber?: bigint | undefined; blockTag?: BlockTag | undefined; } | undefined) => Promise<`0x${string}`>; lastWithdrawalAt: (options?: { ...; } | undefined) => Promise<...>; owner: (options?: { ...; } | undefined) => Promise<...>; }; esti...' but required in type '{ interface: any; }'. [2345]

With contractAt

      const contract = await hre.viem.getContractAt(
        "Inheritance",
        deployedContract.address,
      );

With error

 Argument of type 'GetContractReturnType<[{ inputs: []; stateMutability: "payable"; type: "constructor"; }, { inputs: []; name: "InsufficientBalance"; type: "error"; }, { inputs: []; name: "TooEarlyForInheritance"; type: "error"; }, { inputs: [...]; name: "Unauthorized"; type: "error"; }, ... 7 more ..., { ...; }]>' is not assignable to parameter of type '{ interface: any; }'.
     Property 'interface' is missing in type 'GetContractReturnType<[{ inputs: []; stateMutability: "payable"; type: "constructor"; }, { inputs: []; name: "InsufficientBalance"; type: "error"; }, { inputs: []; name: "TooEarlyForInheritance"; type: "error"; }, { inputs: [...]; name: "Unauthorized"; type: "error"; }, ... 7 more ..., { ...; }]>' but required in type '{ interface: any; }'.

Full test code

I stripped unrelated parts to make a minimal example.

import hre from "hardhat";
import { expect } from "chai";
import {
  loadFixture,
} from "@nomicfoundation/hardhat-toolbox-viem/network-helpers";

describe("Contract", () => {
  async function deployFixture() {
    const [
      [owner, other],
      deployedContract,
      publicClient,
    ] = await Promise.all([
      hre.viem.getWalletClients(),
      hre.viem.deployContract("Inheritance", [], {
        value: BigInt('50'),
      }),
      hre.viem.getPublicClient(),
    ]);

    return {
      owner, other, deployedContract, publicClient,
    }
  };

  describe('Withdraw', () => {
    it('Should block the heir', async () => {
      const { deployedContract, other } = await loadFixture(deployFixture);

      const contract = await hre.viem.getContractAt(
        "Inheritance",
        deployedContract.address,
      );

      await expect(
        contract.write.withdraw([BigInt(0)], {
          account: other.account,
        })
      ).to.be.revertedWithCustomError(
        // Tried with both contract and deployedContract
        deployedContract,
        "Unauthorized"
      );
    });
  });
});

0

There are 0 answers