Skip to content

Commit

Permalink
fix: use eth_maxPriorityFeePerGas for determing gas
Browse files Browse the repository at this point in the history
Update `getFeeData` to match the `ethers` algorithm, specifically don't
just assume `1_000_000_000n` as the `maxPriorityFeePerGas`. Instead call
`eth_maxPriorityFeePerGas`, and only fall back to `1_000_000_000n` if
there is no response.

Fixes #5093
  • Loading branch information
kanej committed May 7, 2024
1 parent c7890f0 commit d62d268
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/smart-hotels-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nomicfoundation/hardhat-ethers": patch
---

Use `eth_maxPriorityFeePerGas` for the max fee per gas calculation if available
11 changes: 10 additions & 1 deletion packages/hardhat-ethers/src/internal/hardhat-ethers-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,16 @@ export class HardhatEthersProvider implements ethers.Provider {
const latestBlock = await this.getBlock("latest");
const baseFeePerGas = latestBlock?.baseFeePerGas;
if (baseFeePerGas !== undefined && baseFeePerGas !== null) {
maxPriorityFeePerGas = 1_000_000_000n;
try {
maxPriorityFeePerGas = BigInt(
await this._hardhatProvider.send("eth_maxPriorityFeePerGas")
);
} catch {
// the max priority fee RPC call is not supported by
// this chain
}

maxPriorityFeePerGas = maxPriorityFeePerGas ?? 1_000_000_000n;
maxFeePerGas = 2n * baseFeePerGas + maxPriorityFeePerGas;
}

Expand Down
83 changes: 78 additions & 5 deletions packages/hardhat-ethers/test/hardhat-ethers-provider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assert, use } from "chai";
import chaiAsPromised from "chai-as-promised";

import { EthereumProvider } from "hardhat/types/provider";
import { HardhatEthersProvider } from "../src/internal/hardhat-ethers-provider";
import { ExampleContract, EXAMPLE_CONTRACT } from "./example-contracts";
import { usePersistentEnvironment } from "./environment";
import { assertIsNotNull, assertWithin } from "./helpers";
Expand Down Expand Up @@ -117,12 +119,83 @@ describe("hardhat ethers provider", function () {
assert.strictEqual(network.chainId, 31337n);
});

it("should return fee data", async function () {
const feeData = await this.env.ethers.provider.getFeeData();
describe("getFeeData", function () {
it("should return fee data", async function () {
const feeData = await this.env.ethers.provider.getFeeData();

assert.typeOf(feeData.gasPrice, "bigint");
assert.typeOf(feeData.maxFeePerGas, "bigint");
assert.typeOf(feeData.maxPriorityFeePerGas, "bigint");
assert.typeOf(feeData.gasPrice, "bigint");
assert.typeOf(feeData.maxFeePerGas, "bigint");
assert.typeOf(feeData.maxPriorityFeePerGas, "bigint");
});

// This helper overrides the send method of an EthereumProvider to allow
// altering the default Hardhat node's reported results.
function overrideSendOn(
provider: EthereumProvider,
sendOveride: (method: string, params?: any[] | undefined) => Promise<any>
) {
return new Proxy(provider, {
get: (target: EthereumProvider, prop: keyof EthereumProvider) => {
if (prop === "send") {
return async (method: string, params?: any[] | undefined) => {
const result = await sendOveride(method, params);

return result ?? target.send(method, params);
};
}

return target[prop];
},
});
}

it("should default maxPriorityFeePerGas to 1 gwei (if eth_maxPriorityFeePerGas not supported)", async function () {
const proxiedProvider = overrideSendOn(
this.env.network.provider,
async (method) => {
if (method !== "eth_maxPriorityFeePerGas") {
// rely on default send implementation
return undefined;
}

throw new Error("Method eth_maxPriorityFeePerGas is not supported");
}
);

const ethersProvider = new HardhatEthersProvider(
proxiedProvider,
this.env.network.name
);

const feeData = await ethersProvider.getFeeData();

assert.equal(feeData.maxPriorityFeePerGas, 1_000_000_000n);
});

it("should default maxPriorityFeePerGas to eth_maxPriorityFeePerGas if available", async function () {
const expectedMaxPriorityFeePerGas = 4_000_000_000n;

const overridenEthereumProvider = overrideSendOn(
this.env.network.provider,
async (method) => {
if (method !== "eth_maxPriorityFeePerGas") {
// rely on default send implementation
return undefined;
}

return expectedMaxPriorityFeePerGas.toString();
}
);

const ethersProvider = new HardhatEthersProvider(
overridenEthereumProvider,
this.env.network.name
);

const feeData = await ethersProvider.getFeeData();

assert.equal(feeData.maxPriorityFeePerGas, 4_000_000_000n);
});
});

describe("getBalance", function () {
Expand Down

0 comments on commit d62d268

Please sign in to comment.