diff --git a/.env.deployments.mainnet b/.env.deployments.mainnet index 5956c4ea1..6b14993d5 100644 --- a/.env.deployments.mainnet +++ b/.env.deployments.mainnet @@ -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 ### diff --git a/constants/rpcUrls.ts b/constants/rpcUrls.ts index dee93aa65..3fdf49a4e 100644 --- a/constants/rpcUrls.ts +++ b/constants/rpcUrls.ts @@ -64,12 +64,12 @@ export const urls: Record = { "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}`, diff --git a/deploy/ChildPool.ts b/deploy/ChildPool.ts index ea8d220ff..ba92c9182 100644 --- a/deploy/ChildPool.ts +++ b/deploy/ChildPool.ts @@ -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; @@ -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); @@ -54,6 +56,8 @@ const deployChildPool: (hre: HardhatRuntimeEnvironment, constructorArgs?: Constr ], log: true, autoMine: true, + maxFeePerGas, + maxPriorityFeePerGas, })) as Deployment; if (live) { diff --git a/deploy/ConceroBridge.ts b/deploy/ConceroBridge.ts index 6d108a4d1..328e26ecd 100644 --- a/deploy/ConceroBridge.ts +++ b/deploy/ConceroBridge.ts @@ -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; @@ -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, @@ -80,6 +82,8 @@ const deployConceroBridge: (hre: HardhatRuntimeEnvironment, constructorArgs?: Co args.messengers, ], autoMine: true, + maxFeePerGas, + maxPriorityFeePerGas, })) as Deployment; if (live) { diff --git a/deploy/ConceroDexSwap.ts b/deploy/ConceroDexSwap.ts index 50e34e69d..3bd0b67e7 100644 --- a/deploy/ConceroDexSwap.ts +++ b/deploy/ConceroDexSwap.ts @@ -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 = async function ( hre: HardhatRuntimeEnvironment, @@ -15,6 +16,7 @@ const deployConceroDexSwap: (hre: HardhatRuntimeEnvironment) => Promise = const networkType = conceroNetworks[name].type; const conceroProxyAddress = getEnvVar(`CONCERO_INFRA_PROXY_${networkEnvKeys[name]}`); + const { maxFeePerGas, maxPriorityFeePerGas } = await getGasParameters(conceroNetworks[name]); log("Deploying...", "DexSwap", name); @@ -23,6 +25,8 @@ const deployConceroDexSwap: (hre: HardhatRuntimeEnvironment) => Promise = args: [conceroProxyAddress, messengers], log: true, autoMine: true, + maxFeePerGas, + maxPriorityFeePerGas, })) as Deployment; if (live) { diff --git a/deploy/ConceroOrchestrator.ts b/deploy/ConceroOrchestrator.ts index 80f437dc8..20e941d7f 100644 --- a/deploy/ConceroOrchestrator.ts +++ b/deploy/ConceroOrchestrator.ts @@ -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 = async function ( hre: HardhatRuntimeEnvironment, @@ -24,9 +25,9 @@ const deployConceroOrchestrator: (hre: HardhatRuntimeEnvironment) => Promise Promise Promise = async function ( hre: HardhatRuntimeEnvironment, @@ -16,6 +17,7 @@ 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", { @@ -23,6 +25,8 @@ const deployProxyAdmin: (hre: HardhatRuntimeEnvironment, proxyType: IProxyType) args: [initialOwner], log: true, autoMine: true, + maxFeePerGas, + maxPriorityFeePerGas, })) as Deployment; if (live) { diff --git a/deploy/ParenPoolCLFCLA.ts b/deploy/ParenPoolCLFCLA.ts index ad60ca72f..0b6c919ce 100644 --- a/deploy/ParenPoolCLFCLA.ts +++ b/deploy/ParenPoolCLFCLA.ts @@ -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; @@ -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]}`), @@ -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", { @@ -56,7 +54,8 @@ const deployParentPoolCLFCLA: (hre: HardhatRuntimeEnvironment, constructorArgs?: ], log: true, autoMine: true, - gasPrice: gasPrice, + maxFeePerGas, + maxPriorityFeePerGas, })) as Deployment; if (live) { diff --git a/deploy/ParentPool.ts b/deploy/ParentPool.ts index bd97da439..fb3804991 100644 --- a/deploy/ParentPool.ts +++ b/deploy/ParentPool.ts @@ -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; @@ -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); @@ -68,7 +70,8 @@ const deployParentPool: (hre: HardhatRuntimeEnvironment, constructorArgs?: Const ], log: true, autoMine: true, - gasPrice: gasPrice, + maxFeePerGas, + maxPriorityFeePerGas, })) as Deployment; if (live) { diff --git a/utils/getGasPrice.ts b/utils/getGasPrice.ts new file mode 100644 index 000000000..ab93e3abb --- /dev/null +++ b/utils/getGasPrice.ts @@ -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 { + 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 { + 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; +}