-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom errors not picked up by Hardhat Network when using external Hardhat artifact #1618
Comments
(Pasting my answer from discord here) It's a known limitation: if a contract is not part of your project, you don't have the information needed to parse the custom error. I don't think there's an easy way to fix that. We want to, at some point, add the capability of using "external" information (e.g., from etherscan), but it's not something we are working on right now The easy fix is to add that contract to your project, for example using hardhat-dependency-compiler |
Oooh, right. I remember reading about this limitation in the release spec:
But I forgot about it. |
I've just bumped into a case where this happens even when the custom errors is defined locally in my project. I have a custom error defined in contract B, which contract A interacts with via DELEGATECALL. When contract B reverts with that custom error, I am getting this error in the console when running my test:
The // Delegate call to the target contract.
(bool success, bytes memory returndata) = target.delegatecall{ gas: stipend }(data);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert();
}
} Therefore I think that adding support for "external" custom errors is more important that we initially thought. Though I am aware that this requires a database like 4byte.directory, which is not easy to generate and maintain. |
Side note: what if Hardhat included the error selector in the logged error? That way, those of us who know how to handle selectors could use them. It happens that ethers.js has a getSighash method for grabbing the 4byte selector. |
Is this delegatecalling into an external contract? Or is the target one also yours? PS: I think this is going to be increasingly more and more important as the custom errors start to get used on mainnet. Otherwise interacting with contracts from mainnet would be painful. |
The target contract is also mine. It is defined in the same repo and I can see an artifacts generated for it. See this:
Yes! Especially true after OpenZeppelin adds support for them. |
Opened #1875 based on this issue. I didn't edit this one because I'm not 100% sure that it's exactly the same problem. |
i understand the technical situation, but is there a way of reading those CustomErrors from the interface? |
Some decisions about this (although we don't know when we'll be able to implement them):
|
What do you mean? |
Let me rephrase: Case scenario: Workaround: |
@PaulRBerg how did you end up testing for the custom errors in hardhat? Do you have an example? |
@PatrickAlphaC I ended up importing the said contract which included the custom error I wanted to test for. I did that by manually importing the contract in my code base, but if you'd like to not write a dummy contract you could instead use hardhat-dependency-compiler. At any rate, this would be much easier to handle if Hardhat managed somehow to decode custom errors from external contracts. |
This would be great although really hard to do in the general case, because you only see a bunch of bytes and you need to guess the signature of the error. Some things we could do are:
But if you are using some obscure contract that is not verified, I think it's just impossible to guess the error. |
This would be epic! Something like 4byte.directory but for custom errors.
Also cool.
That's fine. |
You probably know this already, but the same mechanism is used. That is, custom errors are encoded in the same way that function calls are encoded. So 4byte can include custom errors signatures too. |
I actually didn't know, I didn't read the low-level spec. Fantastic. |
Hi all, I'm living in the 0.6 version of Solidity.
|
@IAliceBobI custom errors don't exist in v0.6 of Solidity. They have been introduced in v0.8.4. There's really no good reason to not upgrade to the latest compiler version. Update: I now see what you wanted to do. Yes, you can replicate the way custom errors are encoded manually, but it's really a chore. If I were you, I would reach out to the developers of the v0.6 libraries you are depending upon, and kindly ask them to upgrade to v0.8. |
I want to upgrade, but I depend on many 0.6 Solidity audited libraries right now. |
@IAliceBobI maybe #2553 can help you with that when it's released. |
I depend on this branch locally, and it works fine! |
@PaulRBerg Curious if you found a fix or workaround for the delegatecall case? I've also been running into this issue recently 🤔 |
Hi @kevincheng96, I can't remember the exact issue I described above, but I think I finally made it work at least in my testing environment. Take a look at the execute.ts file in the prb-proxy repository. |
Great, will take a look at it. Thanks for quick response! |
Looks like @samczsun newly released signature database could be relevant here? |
Hello! In what hardhat version can I find these changes? |
@TsigelnikovNikita I don't remember exactly which version of Hardhat added it, but it should be available in the latest versions. |
Any plans to make it so we can pass in selectors? I run into this problem with running in a fork:
It would be good If we could just do something like:
|
That's not a bad idea. The name of a custom error can't start with |
The syntax would be |
I'm going to close this in favor of #3486, so that we have a single issue tracking this need. |
Description
If I import an artifact from an external package and use Waffle's "deployContract" to deploy it to my local network, and that contract reverts with a custom error, the custom error won't be picked up by Hardhat when running tests.
How to Reproduce
In the terminal:
Then write a test that imports the FintrollerV1 contract and calls the setMaxBonds function. The execution should revert with the OwnableUpgradeable__NotOwner custom error, but it doesn't. It reverts with the following error:
Environment
The text was updated successfully, but these errors were encountered: