Ethereum: Hardhat does not recognize custom errors from legacy contracts

Here is an article based on the provided information:

Ethereum Hardhat doesn’t recognize custom errors from inherited Contracts

When building and testing smart contracts on the Ethereum network using Hardhat, it’s not uncommon to encounter issues with custom error handling. In this case, we’ll explore a common problem that arises when trying to test the TimelockController contract from OpenZeppelin.

The issue: Custom errors in inherited Contracts

To use custom errors in your contracts, you need to import them from an external module (in this case, Address.sol) and then extend their functionality. However, Hardhat has a limitation when it comes to recognizing these custom errors.

Specifically, the TimelockController contract imports FailedCall, which is defined in the Address.sol module. Unfortunately, Hardhat does not recognize these custom errors out-of-the-box.

The solution: Create a separate error module

Ethereum: Hardhat doesn't recognize custom errors from inherited Contracts

To solve this issue, we can create a separate module that defines the custom error called FailedCall. We’ll then import and extend it from our TimelockController contract.

Here’s an example of how you could do this:

// failedcall.sol(new module)

error FailedCall {

msg = "Failed to call function";

}

Then, in your TimelockController contract:

// timelockcontroller.sol (updated contract)

import { Address } from "@openzeppelin/contracts/token/ERC20/SafeToken.sol";

contract TimelockController is SafeToken {

// existing code...

function timelock() public onlyOwner {

try {

// attempt to call the timelock function

_timelock();

} catch (error: FailedCall) {

// handle the custom error

console.log("Failed to call timelock: ", error.msg);

}

}

function _timelock() public onlyOwner {

// implementation of timelock logic...

}

}

Hard Testing

Now that we’ve defined our failedcall.sol module, we can import it and test the custom error in our TimelockController contract using Hardhat.

Here’s an example of how you could do this:

// Hardhat configuration

const hre = require("hard");

const TimelockContract = await hre.getContractFactory("TimelockController");

const timelockContract = await TimelockContract.deploy();

async function main() {

// deploy the contract

const timelockAddress = await timelockContract.address;

try {

// call the timelock function to test the custom error

await timelockContract.timelock();

} catch (error: FailedCall) {

console.log("Failed to call timelock: ", error.msg);

}

}

By creating a separate error module and extending it from our TimelockController contract, we’ve been able to use custom errors in our test. This should help you overcome the issue with Hardhat not recognizing these errors.

Hope this helps! Let me know if you have any questions or need further assistance.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *