Skip to content

Commit

Permalink
feat(ethereum-storage): gas fee multiplier & max gas fee
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandre-abrioux committed Jan 9, 2024
1 parent d2ce64c commit 26b2527
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 9 deletions.
20 changes: 18 additions & 2 deletions packages/ethereum-storage/src/ethereum-tx-submitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { SimpleLogger, isEip1559Supported } from '@requestnetwork/utils';
export type SubmitterProps = {
signer: Signer;
gasPriceMin?: BigNumber;
gasPriceMax?: BigNumber;
gasPriceMultiplier?: number;
network: CurrencyTypes.EvmChainName;
logger?: LogTypes.ILogger;
debugProvider?: boolean;
Expand All @@ -23,15 +25,29 @@ export class EthereumTransactionSubmitter implements StorageTypes.ITransactionSu
private readonly provider: providers.JsonRpcProvider;
private readonly gasFeeDefiner: GasFeeDefiner;

constructor({ network, signer, logger, gasPriceMin, debugProvider }: SubmitterProps) {
constructor({
network,
signer,
logger,
gasPriceMin,
gasPriceMax,
gasPriceMultiplier,
debugProvider,
}: SubmitterProps) {
this.logger = logger || new SimpleLogger();
const provider = signer.provider as providers.JsonRpcProvider;
this.provider = provider;
this.hashSubmitter = requestHashSubmitterArtifact.connect(
network,
signer,
) as RequestOpenHashSubmitter; // type mismatch with ethers.
this.gasFeeDefiner = new GasFeeDefiner({ provider, gasPriceMin, logger: this.logger });
this.gasFeeDefiner = new GasFeeDefiner({
provider,
gasPriceMin,
gasPriceMax,
gasPriceMultiplier,
logger: this.logger,
});
if (debugProvider) {
this.provider.on('debug', (event) => {
this.logger.debug('JsonRpcProvider debug event', event);
Expand Down
16 changes: 13 additions & 3 deletions packages/ethereum-storage/src/gas-fee-definer.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
import { suggestFees } from '@rainbow-me/fee-suggestions';
import { BigNumber, providers, constants } from 'ethers';
import { BigNumber, providers } from 'ethers';
import { normalizeGasFees } from '@requestnetwork/utils';
import { FeeTypes, LogTypes } from '@requestnetwork/types';

export class GasFeeDefiner {
private readonly logger: LogTypes.ILogger;
private readonly provider: providers.JsonRpcProvider;
private readonly gasPriceMin: BigNumber;
private readonly gasPriceMin?: BigNumber;
private readonly gasPriceMax?: BigNumber;
private readonly gasPriceMultiplier?: number;

constructor({
logger,
provider,
gasPriceMin,
gasPriceMax,
gasPriceMultiplier,
}: {
logger: LogTypes.ILogger;
gasPriceMin?: BigNumber;
gasPriceMax?: BigNumber;
gasPriceMultiplier?: number;
provider: providers.JsonRpcProvider;
}) {
this.logger = logger;
this.provider = provider;
this.gasPriceMin = gasPriceMin || constants.Zero;
this.gasPriceMin = gasPriceMin;
this.gasPriceMax = gasPriceMax;
this.gasPriceMultiplier = gasPriceMultiplier;
}

public async getGasFees(): Promise<FeeTypes.EstimatedGasFees> {
return normalizeGasFees({
logger: this.logger,
gasPriceMin: this.gasPriceMin,
gasPriceMax: this.gasPriceMax,
gasPriceMultiplier: this.gasPriceMultiplier,
suggestFees: async () => {
const { baseFeeSuggestion, maxPriorityFeeSuggestions } = await suggestFees(this.provider);
return {
Expand Down
17 changes: 13 additions & 4 deletions packages/utils/src/normalize-gas-fees.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BigNumber, constants } from 'ethers';

import { maxBigNumber } from './index';
import { maxBigNumber, minBigNumber } from './index';
import { LogTypes, FeeTypes } from '@requestnetwork/types';

/**
Expand All @@ -14,22 +14,31 @@ import { LogTypes, FeeTypes } from '@requestnetwork/types';
async function normalizeGasFees({
logger,
gasPriceMin,
gasPriceMax,
gasPriceMultiplier,
suggestFees,
}: {
logger: LogTypes.ILogger;
gasPriceMin?: BigNumber;
gasPriceMax?: BigNumber;
gasPriceMultiplier?: number;
suggestFees: () => Promise<FeeTypes.SuggestedFees>;
}): Promise<FeeTypes.EstimatedGasFees> {
try {
const suggestedFee = await suggestFees();

const baseFee = maxBigNumber(suggestedFee.baseFee, gasPriceMin || constants.Zero);

const maxPriorityFeePerGas = maxBigNumber(
suggestedFee.maxPriorityFee,
gasPriceMin || constants.Zero,
);
const maxFeePerGas = baseFee.add(maxPriorityFeePerGas);

const maxFeePerGasInit = baseFee
.add(maxPriorityFeePerGas)
.mul(gasPriceMultiplier || 100)
.div(100);
const maxFeePerGas = gasPriceMax
? minBigNumber(maxFeePerGasInit, gasPriceMax)
: maxFeePerGasInit;

if (maxPriorityFeePerGas.eq(0) || maxFeePerGas.eq(0)) {
logger.warn(
Expand Down
26 changes: 26 additions & 0 deletions packages/utils/test/normalize-gas-fees.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,30 @@ describe('Normalize Gas Fees', () => {
expect(normalizedGasFees.maxPriorityFeePerGas?.toString()).toBe('1000000000');
expect(normalizedGasFees.maxFeePerGas?.toString()).toBe('2000000000');
});

it('should respect maximum gas fee', async () => {
const normalizedGasFees = await normalizeGasFees({
logger: console,
suggestFees: async () => ({
baseFee: '400000000000', // 400 Gwei
maxPriorityFee: '2000000000', // 2 Gwei
}),
gasPriceMax: BigNumber.from('250000000000'), // 250 Gwei
});
expect(normalizedGasFees.maxPriorityFeePerGas?.toString()).toBe('2000000000'); // 2 Gwei
expect(normalizedGasFees.maxFeePerGas?.toString()).toBe('250000000000'); // 250 Gwei
});

it('should respect gas multiplier', async () => {
const normalizedGasFees = await normalizeGasFees({
logger: console,
suggestFees: async () => ({
baseFee: '20000000000', // 20 Gwei
maxPriorityFee: '2000000000', // 2 Gwei
}),
gasPriceMultiplier: 200, // x2
});
expect(normalizedGasFees.maxPriorityFeePerGas?.toString()).toBe('2000000000'); // 2 Gwei
expect(normalizedGasFees.maxFeePerGas?.toString()).toBe('44000000000'); // (20 + 2) x 2 = 44 Gwei
});
});

0 comments on commit 26b2527

Please sign in to comment.