setNextBlockBaseFeePerGas doesn't work on views and callStatic methods
contract Example {
function aView(){
_getBaseFee();
}
function aMethod(){
_getBaseFee();
}
function _getBaseFee(){
console.log(block.basefee);
}
When calling such contract after:
await network.provider.request({
method: 'hardhat_setNextBlockBaseFeePerGas',
params: [BigNumber.from(100e9).toHexString()],
}
-
Example.aView() -
Example.callStatic.aMethod() -
Example.aMethod()
It will print both 0 for aView() and callStatic.aMethod() and will print 100e9 for aMethod()
Such behaviour doesn't allow to perform tests that require a view that depends on the block.basefee
This issue is also being tracked on Linear.
We use Linear to manage our development process, but we keep the conversations on Github.
LINEAR-ID: 15015ad4-c6ff-4c0a-8818-4bc91589d064
Hey @wei3erHase !
Have you tried running using blocktag "pending"? eth_calls are run using the latest block by default.
ey @alcuadrado, have tried now both pending, and trying advancing one block and using blocktag latest, same results :(
Thanks for confirming. This has to be a bug then
Any news on this one?
I tested this with the latest Hardhat version, and in all cases, calling block.basefee inside the contract returns 0. However, fetching the base fee with ethers returns the correct value. This seems off, so I'm handing it over to EDR for investigation.
Code reference:
// contracts/Example.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;
import "hardhat/console.sol";
contract Example {
function aView() public view {
_getBaseFee();
}
function aMethod() public view {
_getBaseFee();
}
function _getBaseFee() public view {
console.log("\t\tBlock number:", block.number);
console.log("\t\tBlock base fee:", block.basefee);
}
}
// script.ts
import hre from "hardhat";
import { formatUnits } from "ethers";
async function main() {
let block = await hre.ethers.provider.getBlock("latest");
console.log("Current block number:", block?.number);
console.log(
"Current base fee:",
formatUnits(block?.baseFeePerGas ?? 0n, "gwei") + " gwei"
);
console.log("\nCalling hardhat_setNextBlockBaseFeePerGas...");
await hre.network.provider.request({
method: "hardhat_setNextBlockBaseFeePerGas",
params: ["0x" + BigInt(100e9).toString(16)],
});
block = await hre.ethers.provider.getBlock("latest");
console.log("Current block number:", block?.number);
console.log(
"Current base fee:",
formatUnits(block?.baseFeePerGas ?? 0n, "gwei") + " gwei"
);
console.log("\nDeploying contract...");
const Example = await hre.ethers.getContractFactory("Example");
const contract = await Example.deploy();
block = await hre.ethers.provider.getBlock("latest");
console.log("Current block number:", block?.number);
console.log(
"Current base fee:",
formatUnits(block?.baseFeePerGas ?? 0n, "gwei") + " gwei"
);
console.log("\nCalling contract methods...");
console.log("\taView():");
await contract.aView();
console.log("\taMethod.staticCall():");
await contract.aMethod.staticCall();
console.log("\taMethod():");
await contract.aMethod();
block = await hre.ethers.provider.getBlock("latest");
console.log("Current block number:", block?.number);
console.log(
"Current base fee:",
formatUnits(block?.baseFeePerGas ?? 0n, "gwei") + " gwei"
);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Output:
❯ npx hardhat run script.ts
Current block number: 0
Current base fee: 1.0 gwei
Calling hardhat_setNextBlockBaseFeePerGas...
Current block number: 0
Current base fee: 1.0 gwei
Deploying contract...
Current block number: 1
Current base fee: 100.0 gwei
Calling contract methods...
aView():
Block number: 1
Block base fee: 0
aMethod.staticCall():
Block number: 1
Block base fee: 0
aMethod():
Block number: 1
Block base fee: 0
Current block number: 1
Current base fee: 100.0 gwei