hardhat
hardhat copied to clipboard
Wrong inferred error when a view-function of a library is called and it reverts
Deploying and calling a library's view function in a mainnet fork pinned at a certain block sometimes results in:
Error: Transaction reverted: library was called directly.
That behaviour is unexpected and doesn't correlate to mainnet behaviour. Libraries pure and view functions should be callable from an external account. Interacting with the same library from an external account on mainnet returns a proper value when calling the same view function.
When changing the pinned block it seems that the issue is sometimes resolved. No exact steps to reproduce.
Minimal example: A library with one view function which returns a number and a script, which deploys the library, and calls the view function. Run with mainnet forking enabled and pinned at a block.
A library with one view function which returns a number and a script, which deploys the library, and calls the view function. Run with mainnet forking enabled and pinned at a block.
I did this and couldn't reproduce the problem. Works fine with and without forking, and with and without a pinned block.
After a bit more digging, turned out that the function really was reverted, but the error message was incorrect.
Error message should have been "SafeMath: multiplication overflow"
Oh, that's interesting. Is there a chance you can make a minimal example of that? It could be a bug in our tracer.
Yeah, so basically you can do something like this:
function test() public view returns(uint256) {
require(msg.sender == 0x0000000000000000000000000000000000000000, "Error");
return 1;
}
And call that function on the library to receive the error:
library was called directly
Thanks!
Which compiler version are you using, @ivanzhelyazkov?
Which compiler version are you using, @ivanzhelyazkov?
0.7.6, @alcuadrado
I'm also having this issue, but I haven't been able to work out the true reason for the revert.
Is this only occuring for "SafeMath: multiplication overflow"?
I"m confident it's an incorrect trace because I can run other functions from the same library just fine.
Thanks!
This error will also be reported when running test case on the local network.
Can you provide a reproduction repository? Thanks!
Just ran into this issue recently, any update on a fix or any workaround?
I'm experiencing this locally with a pure function in a library also. I'm attempting to write tests for the following function:
function push(RingBuffer calldata buf, int256 x) public pure returns (RingBuffer memory) {
int256[] memory ys = buf.xs;
if (buf.write == buf.n) {
ys[0] = x;
return RingBuffer(ys, buf.n, 1, buf.read);
} else {
ys[buf.write] = x;
return RingBuffer(ys, buf.n, buf.write + 1, buf.read);
}
}
In the test suite:
/* ... */
const actualBuffer = await library.push(initialBuffer, someElem)
/* ... */
This errors with:
Error: Transaction reverted: library was called directly
at PoolSwapLibrary.<unknown> (contracts/implementation/PoolSwapLibrary.sol:7)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at runNextTicks (internal/process/task_queues.js:66:3)
at listOnTimeout (internal/timers.js:518:9)
at processTimers (internal/timers.js:492:7)
at async HardhatNode.runCall (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:510:20)
at async EthModule._callAction (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:353:9)
at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:106:18)
@sporejack see the above mentioned issue for calling library's pure functions using struct
This issue was marked as stale because it didn't have any activity in the last 30 days. If you think it's still relevant, please leave a comment indicating so. Otherwise, it will be closed in 7 days.
This issue was closed because it has been stalled for 7 days with no activity.
Hey folks, any additional info on this one? I'm running into the same issue while converting an existing test suite over to hardhat
We are checking for expected reverts from the library methods, but instead seeing Transaction reverted: library was called directly
All valid calls (to the same methods) are working fine.
For example intentionally triggering this revert
function userShareSeconds(
address module,
address addr,
uint256 shares
) public view returns (uint256, uint256) {
require(shares > 0, "crmi1");
...
yields the following error
Wrong kind of exception received
+ expected - actual
-Transaction reverted: library was called directly
+crmi1
Hi @fvictorio @alcuadrado @ivanzhelyazkov has anyone found a solution for this? Currently my workaround is to just expect a generic revert
I tried to reproduce this error with the suggestion from @ivanzhelyazkov at https://github.com/hiroshitash/hardhat-inferred-error, but I wasn't able to.
Instead, I receive the following error, which seems correct.
% npx hardhat run --network localhost scripts/deploy.js
Compiled 2 Solidity files successfully
Error: call revert exception; VM Exception while processing transaction: reverted with reason string "" [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="test()", data="0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", errorArgs=[""], errorName="Error", errorSignature="Error(string)", reason="", code=CALL_EXCEPTION, version=abi/5.7.0)
at Logger.makeError (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
at Interface.decodeFunctionResult (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/abi/src.ts/interface.ts:427:23)
at Contract.<anonymous> (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/contracts/src.ts/index.ts:400:44)
at step (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/contracts/lib/index.js:48:23)
at Object.next (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/contracts/lib/index.js:29:53)
at fulfilled (/Users/hirotashiro/hardhat-inferred-error/node_modules/@ethersproject/contracts/lib/index.js:20:58)
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
reason: '',
code: 'CALL_EXCEPTION',
method: 'test()',
data: '0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000',
errorArgs: [ '' ],
errorName: 'Error',
errorSignature: 'Error(string)',
address: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9',
args: [],
transaction: {
data: '0xf8a8fd6d',
to: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9',
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'
}
}
Hardhat version tested is 2.14.0
% npx hardhat --version
2.14.0
Check at this._isDirectLibraryCall(trace) looks suspicious, but it might be hard to reproduce without hardhat version and repo.
_isDirectLibraryCall is defined here.
private _isDirectLibraryCall(trace: DecodedCallMessageTrace): boolean {
return (
trace.depth === 0 && trace.bytecode.contract.type === ContractType.LIBRARY
);
}
Hey @hiroshitash thanks for the response. Here's an example that might be useful in reproducing the issue https://github.com/gysr-io/core/blob/614dfffb97cb136190594849c50b29766341f3cd/test/unit/erc20competitiverewardmoduleinfo.js#L127-L137
@devinaconley I found the root cause of your error library was called directly. It's because ERC20CompetitiveRewardModuleInfo is library (not contract) here
library ERC20CompetitiveRewardModuleInfo {
using GysrUtils for uint256;
If you change it to contract like below, the error disappears.
contract ERC20CompetitiveRewardModuleInfo {
using GysrUtils for uint256;
Library calls are checked here with this._isDirectLibraryCall(trace).
The error can be reproduced at https://github.com/hiroshitash/hardhat-inferred-error
I´m having the same issue. It was working fine when I was calling it before as a library w/o any issues until now recently. Problem is, it is not a contract but a genuine library. Please help!
@Samboy76 The error message library was called directly is hiding your original error so I suggest the followings:
- Temporarily change
librarytocontract(in order to hidelibrary was called directlyerror). - Compile with
yarn hardhat compileornpx hardhat compile. It should show your original error. - Fix the original error, change back
contracttolibrary, and try compiling again.
As for the change in Hardhat, I think the lines below can be removed as it is hiding the original error message.
if (this._isDirectLibraryCall(trace)) {
return this._getDirectLibraryCallErrorStackTrace(trace);
}
@devinaconley I found the root cause of your error
library was called directly. It's becauseERC20CompetitiveRewardModuleInfois library (not contract) here
thanks for the response and suggestiong @hiroshitash -- in our case, the libraries are designed to be stateless and called directly, so unfortunately switching to a contract is not a viable workaround