Skip to content

Commit

Permalink
maxFeePerGas + maxPriorityFeePerGas calculation util
Browse files Browse the repository at this point in the history
  • Loading branch information
olegkron committed Jan 13, 2025
1 parent 2575739 commit 7a6ac8a
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 14 deletions.
6 changes: 3 additions & 3 deletions .env.deployments.mainnet
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ CONCERO_INFRA_PROXY_ADMIN_ARBITRUM=0xF069f384a177083c4d62539e187860d2e163b0F4
CONCERO_BRIDGE_OPTIMISM=0xe66eEDe2D32f9BE9E668f39897B5d9820A81eb40
CONCERO_BRIDGE_BASE=0x09F52d772A7DFCBE20461920802eb79a3c6cf4BC
CONCERO_BRIDGE_ARBITRUM=0x54D452Cef1d98cF2B03B444481Ba545e8DBFF48F
CONCERO_BRIDGE_POLYGON=0xA0b0a1E9bb37417CBB0aBd49ab4bCA329c1F7a4C
CONCERO_BRIDGE_POLYGON=0x81d1B6a2D512c1cd796B7D203F8DBCe9A11F7b97
CONCERO_BRIDGE_AVALANCHE=0x2877BA64A0f7aD99adA9d787C0FEC3c92699fb34

# DEX SWAP MAINNET
CONCERO_DEX_SWAP_OPTIMISM=0xb8840BC9ea27df2480F7906D3791219D2685eBe9
CONCERO_DEX_SWAP_BASE=0x36D6cDcC892D9da3F57a19b623ddf100B04Fd804
CONCERO_DEX_SWAP_ARBITRUM=0xA0b0a1E9bb37417CBB0aBd49ab4bCA329c1F7a4C
CONCERO_DEX_SWAP_POLYGON=0xf678A3Dd84f0a04cEC6cD0Ef2eAf14eA9135603C
CONCERO_DEX_SWAP_POLYGON=0x57ca203C6FCC8d959D41992c0924fA6046466442
CONCERO_DEX_SWAP_AVALANCHE=0xf36447cA4dA784c2f50215D75035743484b124CB

# ORCHESTRATOR MAINNET
CONCERO_ORCHESTRATOR_OPTIMISM=0x22589e84b36c9AA546C38ef47a5235C21Fde6Bdc
CONCERO_ORCHESTRATOR_BASE=0x871849c092E4A8D4821e6196439AAdCb43c35bad
CONCERO_ORCHESTRATOR_ARBITRUM=0x44808558017740cB681D67D2015C402dfd11F733
CONCERO_ORCHESTRATOR_POLYGON=0x54D452Cef1d98cF2B03B444481Ba545e8DBFF48F
CONCERO_ORCHESTRATOR_POLYGON=0x8d620E1D7c20Da854B29d98F0c4Cebe826CeAc60
CONCERO_ORCHESTRATOR_AVALANCHE=0xf139e1a078ca386d895b2C5B17A39A83fC8d0745

### CHILD POOLS PROXY MAINNET ###
Expand Down
4 changes: 2 additions & 2 deletions constants/rpcUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ export const urls: Record<string, string[]> = {
"https://rpc.ankr.com/optimism_sepolia",
],
polygon: [
"https://polygon-bor-rpc.publicnode.com",
`https://lb.drpc.org/ogrpc?network=polygon&dkey=${DRPC_API_KEY}`,
`https://polygon.gateway.tenderly.co/${TENDERLY_API_KEY}`,
`https://polygon-mainnet.blastapi.io/${BLAST_API_KEY}`,
"https://rpc.ankr.com/polygon",
`https://polygon.gateway.tenderly.co/${TENDERLY_API_KEY}`,
`https://polygon-mainnet.infura.io/v3/${INFURA_API_KEY}`,
"https://polygon-bor-rpc.publicnode.com",
],
polygonAmoy: [
`https://lb.drpc.org/ogrpc?network=polygon-amoy&dkey=${DRPC_API_KEY}`,
Expand Down
4 changes: 4 additions & 0 deletions deploy/ChildPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import updateEnvVariable from "../utils/updateEnvVariable";
import log from "../utils/log";
import { getEnvVar } from "../utils";
import { poolMessengers } from "../constants";
import { getGasParameters } from "../utils/getGasPrice";

interface ConstructorArgs {
conceroProxyAddress?: string;
Expand Down Expand Up @@ -38,6 +39,7 @@ const deployChildPool: (hre: HardhatRuntimeEnvironment, constructorArgs?: Constr

// Merge defaultArgs with constructorArgs
const args = { ...defaultArgs, ...constructorArgs };
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

log("Deploying...", "deployChildPool", name);

Expand All @@ -54,6 +56,8 @@ const deployChildPool: (hre: HardhatRuntimeEnvironment, constructorArgs?: Constr
],
log: true,
autoMine: true,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
4 changes: 4 additions & 0 deletions deploy/ConceroBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import updateEnvVariable from "../utils/updateEnvVariable";
import log from "../utils/log";
import { getEnvVar } from "../utils";
import { messengers } from "../constants";
import { getGasParameters, getGasPrice } from "../utils/getGasPrice";

interface ConstructorArgs {
slotId?: number;
Expand Down Expand Up @@ -64,6 +65,7 @@ const deployConceroBridge: (hre: HardhatRuntimeEnvironment, constructorArgs?: Co
};

const args = { ...defaultArgs, ...constructorArgs };
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

const deployment = (await deploy("ConceroBridge", {
from: deployer,
Expand All @@ -80,6 +82,8 @@ const deployConceroBridge: (hre: HardhatRuntimeEnvironment, constructorArgs?: Co
args.messengers,
],
autoMine: true,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
8 changes: 6 additions & 2 deletions deploy/ConceroDexSwap.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Deployment } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import conceroNetworks, { networkEnvKeys } from "../constants/conceroNetworks";
import { conceroNetworks, networkEnvKeys } from "../constants/conceroNetworks";
import updateEnvVariable from "../utils/updateEnvVariable";
import log from "../utils/log";
import { getEnvVar } from "../utils";
import { getEnvVar, getFallbackClients } from "../utils";
import { messengers } from "../constants";
import { getGasParameters, getGasPrice } from "../utils/getGasPrice";

const deployConceroDexSwap: (hre: HardhatRuntimeEnvironment) => Promise<void> = async function (
hre: HardhatRuntimeEnvironment,
Expand All @@ -15,6 +16,7 @@ const deployConceroDexSwap: (hre: HardhatRuntimeEnvironment) => Promise<void> =
const networkType = conceroNetworks[name].type;

const conceroProxyAddress = getEnvVar(`CONCERO_INFRA_PROXY_${networkEnvKeys[name]}`);
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

log("Deploying...", "DexSwap", name);

Expand All @@ -23,6 +25,8 @@ const deployConceroDexSwap: (hre: HardhatRuntimeEnvironment) => Promise<void> =
args: [conceroProxyAddress, messengers],
log: true,
autoMine: true,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
5 changes: 4 additions & 1 deletion deploy/ConceroOrchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import updateEnvVariable from "../utils/updateEnvVariable";
import log from "../utils/log";
import { getEnvVar } from "../utils";
import { messengers } from "../constants";
import { getGasParameters, getGasPrice } from "../utils/getGasPrice";

const deployConceroOrchestrator: (hre: HardhatRuntimeEnvironment) => Promise<void> = async function (
hre: HardhatRuntimeEnvironment,
Expand All @@ -24,9 +25,9 @@ const deployConceroOrchestrator: (hre: HardhatRuntimeEnvironment) => Promise<voi
: getEnvVar(`CHILD_POOL_PROXY_${networkEnvKeys[name]}`);

const conceroProxyAddress = getEnvVar(`CONCERO_INFRA_PROXY_${networkEnvKeys[name]}`);
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

log("Deploying...", "ConceroOrchestrator", name);

const conceroProxyDeployment = (await deploy("InfraOrchestrator", {
from: deployer,
args: [
Expand All @@ -40,6 +41,8 @@ const deployConceroOrchestrator: (hre: HardhatRuntimeEnvironment) => Promise<voi
],
log: true,
autoMine: true,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
4 changes: 4 additions & 0 deletions deploy/ConceroProxyAdmin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getEnvVar, updateEnvAddress } from "../utils";
import log from "../utils/log";

import { IProxyType } from "../types/deploymentVariables";
import { getGasParameters } from "../utils/getGasPrice";

const deployProxyAdmin: (hre: HardhatRuntimeEnvironment, proxyType: IProxyType) => Promise<void> = async function (
hre: HardhatRuntimeEnvironment,
Expand All @@ -16,13 +17,16 @@ const deployProxyAdmin: (hre: HardhatRuntimeEnvironment, proxyType: IProxyType)
const networkType = conceroNetworks[name].type;

const initialOwner = getEnvVar(`PROXY_DEPLOYER_ADDRESS`);
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

log("Deploying...", `deployProxyAdmin: ${proxyType}`, name);
const deployProxyAdmin = (await deploy("ConceroProxyAdmin", {
from: proxyDeployer,
args: [initialOwner],
log: true,
autoMine: true,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
9 changes: 4 additions & 5 deletions deploy/ParenPoolCLFCLA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import updateEnvVariable from "../utils/updateEnvVariable";
import log from "../utils/log";
import { getEnvVar, getFallbackClients } from "../utils";
import { poolMessengers } from "../constants";
import { getGasParameters } from "../utils/getGasPrice";

interface Args {
parentProxyAddress: string;
Expand All @@ -25,6 +26,7 @@ const deployParentPoolCLFCLA: (hre: HardhatRuntimeEnvironment, constructorArgs?:
const networkType = cNetwork.type;

const { functionsRouter, functionsSubIds, functionsDonId } = cNetwork;
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

const defaultArgs: Args = {
parentProxyAddress: getEnvVar(`PARENT_POOL_PROXY_${networkEnvKeys[name]}`),
Expand All @@ -37,10 +39,6 @@ const deployParentPoolCLFCLA: (hre: HardhatRuntimeEnvironment, constructorArgs?:
};

const args = { ...defaultArgs, ...constructorArgs };

const { publicClient: viemPublicClient } = getFallbackClients(conceroNetworks[name]);
const gasPrice = await viemPublicClient.getGasPrice();

console.log("Deploying parent pool clf cla...");

const deployParentPoolCLFCLA = (await deploy("ParentPoolCLFCLA", {
Expand All @@ -56,7 +54,8 @@ const deployParentPoolCLFCLA: (hre: HardhatRuntimeEnvironment, constructorArgs?:
],
log: true,
autoMine: true,
gasPrice: gasPrice,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
5 changes: 4 additions & 1 deletion deploy/ParentPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import log from "../utils/log";
import { zeroAddress } from "viem";
import { getEnvVar, getFallbackClients } from "../utils";
import { poolMessengers } from "../constants";
import { getGasParameters } from "../utils/getGasPrice";

interface Args {
parentProxyAddress: string;
Expand Down Expand Up @@ -45,6 +46,7 @@ const deployParentPool: (hre: HardhatRuntimeEnvironment, constructorArgs?: Const

// Merge defaultArgs with constructorArgs
const args = { ...defaultArgs, ...constructorArgs };
const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]);

log("Deploying...", `deployParentPool, ${deployer}`, name);

Expand All @@ -68,7 +70,8 @@ const deployParentPool: (hre: HardhatRuntimeEnvironment, constructorArgs?: Const
],
log: true,
autoMine: true,
gasPrice: gasPrice,
maxFeePerGas,
maxPriorityFeePerGas,
})) as Deployment;

if (live) {
Expand Down
127 changes: 127 additions & 0 deletions utils/getGasPrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { CNetwork } from "../types/CNetwork";
import { getFallbackClients } from "./getViemClients";
import { type PublicClient } from "viem";

interface GasParameters {
maxFeePerGas: bigint;
maxPriorityFeePerGas: bigint;
}

// Network-specific minimum gas parameters (in wei)
const NETWORK_MINIMUMS = {
polygon: {
minTipCap: BigInt(30_000_000_000), // 30 gwei
minBaseFee: BigInt(30_000_000_000), // 30 gwei
},
// Add other networks as needed
} as const;

/**
* Gets optimized gas parameters for priority transaction processing
* @param chain - The network configuration
* @param priorityMultiplier - Multiplier for maxPriorityFeePerGas (default: 2)
* @param maxFeeMultiplier - Multiplier for maxFeePerGas buffer (default: 2)
* @returns GasParameters object containing maxFeePerGas and maxPriorityFeePerGas
*/
export async function getGasParameters(
chain: CNetwork,
priorityMultiplier = 2,
maxFeeMultiplier = 2,
): Promise<GasParameters> {
const { publicClient } = getFallbackClients(chain);

try {
// Get latest block to calculate gas parameters
const block = await publicClient.getBlock();
const baseFee = block.baseFeePerGas ?? BigInt(0);

// Get network-specific minimums
const networkMinimums = getNetworkMinimums(chain);

// Calculate priority fee with buffer for faster inclusion
const suggestedPriorityFee = await getSuggestedPriorityFee(publicClient, chain);
const calculatedPriorityFee = calculatePriorityFee(suggestedPriorityFee, priorityMultiplier);

// Ensure priority fee meets network minimum
const priorityFee =
calculatedPriorityFee > networkMinimums.minTipCap ? calculatedPriorityFee : networkMinimums.minTipCap;

// Calculate max fee ensuring it meets network minimums
const calculatedMaxFee = calculateMaxFee(baseFee, priorityFee, maxFeeMultiplier);
const minRequiredMaxFee = networkMinimums.minBaseFee + priorityFee;
const maxFeePerGas = calculatedMaxFee > minRequiredMaxFee ? calculatedMaxFee : minRequiredMaxFee;

return {
maxFeePerGas,
maxPriorityFeePerGas: priorityFee,
};
} catch (error) {
// Fallback with network minimums
const networkMinimums = getNetworkMinimums(chain);
const gasPrice = await publicClient.getGasPrice();
const priorityFee = networkMinimums.minTipCap;

return {
maxFeePerGas:
gasPrice > networkMinimums.minBaseFee + priorityFee ? gasPrice : networkMinimums.minBaseFee + priorityFee,
maxPriorityFeePerGas: priorityFee,
};
}
}

/**
* Gets network-specific minimum gas parameters
*/
function getNetworkMinimums(chain: CNetwork) {
// Check if chain is Polygon (you'll need to implement this check based on your CNetwork type)
const isPolygon = chain.chainId === 137 || chain.name.toLowerCase().includes("polygon");

if (isPolygon) {
return NETWORK_MINIMUMS.polygon;
}

// Default minimums for other networks
return {
minTipCap: BigInt(1_500_000_000), // 1.5 gwei
minBaseFee: BigInt(1_000_000_000), // 1 gwei
};
}

/**
* Gets the suggested priority fee from recent blocks
*/
async function getSuggestedPriorityFee(publicClient: PublicClient, chain: CNetwork): Promise<bigint> {
try {
// For Polygon, we want to be more aggressive with priority fees
const isPolygon = chain.chainId === 137 || chain.name.toLowerCase().includes("polygon");
const blocksToAnalyze = isPolygon ? 5 : 10; // Look at fewer blocks on Polygon for more recent data

const blocks = await Promise.all(
Array.from({ length: blocksToAnalyze }, (_, i) => publicClient.getBlock({ blockNumber: BigInt(-1 - i) })),
);

// For Polygon, use 75th percentile instead of median for higher priority
const priorityFees = blocks.map(block => block.baseFeePerGas ?? BigInt(0)).sort((a, b) => (a < b ? -1 : 1));

const index = isPolygon ? Math.floor(priorityFees.length * 0.75) : Math.floor(priorityFees.length * 0.5);

return priorityFees[index];
} catch {
// Use network-specific minimum as fallback
return getNetworkMinimums(chain).minTipCap;
}
}

/**
* Calculates priority fee with buffer
*/
function calculatePriorityFee(basePriorityFee: bigint, multiplier: number): bigint {
return BigInt(Math.ceil(Number(basePriorityFee) * multiplier));
}

/**
* Calculates max fee with buffer
*/
function calculateMaxFee(baseFee: bigint, priorityFee: bigint, multiplier: number): bigint {
return BigInt(Math.ceil(Number(baseFee) * multiplier)) + priorityFee;
}

0 comments on commit 7a6ac8a

Please sign in to comment.