diff --git a/.env.clf b/.env.clf index bbd18685..c437ff2c 100644 --- a/.env.clf +++ b/.env.clf @@ -28,10 +28,10 @@ CLF_DON_SECRETS_VERSION_POLYGON_AMOY=1718960274 # mainnet CLF_DON_SECRETS_VERSION_MAINNET=0 -CLF_DON_SECRETS_VERSION_ARBITRUM=1725384925 -CLF_DON_SECRETS_VERSION_POLYGON=1725385038 -CLF_DON_SECRETS_VERSION_AVALANCHE=1725385012 -CLF_DON_SECRETS_VERSION_BASE=1725385231 +CLF_DON_SECRETS_VERSION_ARBITRUM=1733158740 +CLF_DON_SECRETS_VERSION_POLYGON=1733158826 +CLF_DON_SECRETS_VERSION_AVALANCHE=1733158902 +CLF_DON_SECRETS_VERSION_BASE=1733159389 # DON-HOSTED SECRETS VERSIONS EXPIRATION TIMESTAMPS # testnet diff --git a/.env.deployments.mainnet b/.env.deployments.mainnet index 27c8fc39..97e3c650 100644 --- a/.env.deployments.mainnet +++ b/.env.deployments.mainnet @@ -11,22 +11,22 @@ CONCERO_INFRA_PROXY_ADMIN_POLYGON=0xF069f384a177083c4d62539e187860d2e163b0F4 CONCERO_INFRA_PROXY_ADMIN_ARBITRUM=0xF069f384a177083c4d62539e187860d2e163b0F4 # BRIDGE CONTRACTS MAINNET -CONCERO_BRIDGE_BASE=0x9c3Ab328f91A82a0a63896ebaC92364Ea527AaFf -CONCERO_BRIDGE_ARBITRUM=0x7b7559f6B96D579D0fEf3E27FfE22fb8d9AA6ab3 -CONCERO_BRIDGE_POLYGON=0x9F8b3FF9Dc6c678d1f1CC4Dd01Bd1ff05cE8B37D -CONCERO_BRIDGE_AVALANCHE=0xfBE0d5d19C52a70dD4F98179339575747e01c154 +CONCERO_BRIDGE_BASE=0x9df0d210D8E69F5b8c5557793cFB9c6e8b5cfEbC +CONCERO_BRIDGE_ARBITRUM=0xE208a351A383d7660493105deDAf02816D9b6a53 +CONCERO_BRIDGE_POLYGON=0x1F5CD9dF512Ed6179e66Cc4274B52e378d0ba13e +CONCERO_BRIDGE_AVALANCHE=0x2877BA64A0f7aD99adA9d787C0FEC3c92699fb34 # DEX SWAP MAINNET -CONCERO_DEX_SWAP_BASE=0xC92033cb11E937E438FEfA1066A10447fD5f774B -CONCERO_DEX_SWAP_ARBITRUM=0xeDF1e1a7d5B73A4Eeee5BDC4824a116814e50134 -CONCERO_DEX_SWAP_POLYGON=0xE5c7a1821C9D392ae53cCCf6758914edA20f5018 -CONCERO_DEX_SWAP_AVALANCHE=0x3d49A0044B6B4b3aF6644C5457B7C69801693D34 +CONCERO_DEX_SWAP_BASE=0x1fC5D335B5A8D2c38AE5d2CC9b4123D993204Cb1 +CONCERO_DEX_SWAP_ARBITRUM=0x96660996CA3DbA4635B3bc4Cd904763648F0427c +CONCERO_DEX_SWAP_POLYGON=0x59863451C386669B085369da350CA00a27C3B1c6 +CONCERO_DEX_SWAP_AVALANCHE=0xf36447cA4dA784c2f50215D75035743484b124CB # ORCHESTRATOR MAINNET -CONCERO_ORCHESTRATOR_BASE=0x0b55581C39bE50fFfa1C275EbE00140d7B3B2A8c -CONCERO_ORCHESTRATOR_ARBITRUM=0xA3ccaA89963668e44456bA4db165c22C89C996fA -CONCERO_ORCHESTRATOR_POLYGON=0x4b5d1694c9879c5Ed132a1970fd88895D11C7bCb -CONCERO_ORCHESTRATOR_AVALANCHE=0x157e124a942b7d7Df2b5137f921Ad1FDdf576126 +CONCERO_ORCHESTRATOR_BASE=0xA0AaF3A0B1771d923dc287a5274E28f1192a54dE +CONCERO_ORCHESTRATOR_ARBITRUM=0xe7736f136247960aC09ACDf51219Ea4BD83f2381 +CONCERO_ORCHESTRATOR_POLYGON=0xbc618869da6545863C31Ce6d65A1Bd8BEd59DF00 +CONCERO_ORCHESTRATOR_AVALANCHE=0xf139e1a078ca386d895b2C5B17A39A83fC8d0745 ### CHILD POOLS PROXY MAINNET ### CHILD_POOL_PROXY_ARBITRUM=0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d @@ -39,9 +39,9 @@ CHILD_POOL_PROXY_ADMIN_AVALANCHE=0x3888A36fF10D894DA4000c94340C40761138C69F CHILD_POOL_PROXY_ADMIN_POLYGON=0x3888A36fF10D894DA4000c94340C40761138C69F ### CHILD POOLS IMPLEMENTATIONS MAINNET ### -CHILD_POOL_ARBITRUM=0x33a3d7150D13798B1f4163F62bC5070336fDda0B -CHILD_POOL_POLYGON=0xb519dF56532140190D7fCD71fb6AC2915089C92E -CHILD_POOL_AVALANCHE=0xBE7b5f0F11E297F9b0a2a7400ca597e1c627639f +CHILD_POOL_ARBITRUM=0x0786fF7667393A926A19812F45c510BF148E9e07 +CHILD_POOL_POLYGON=0x021CA4CFDFaDFc0Ec78731a6467d7e4110E2aFe8 +CHILD_POOL_AVALANCHE=0xE6F7331FBf3aC0d2431Fa6e8E30025C27227Dc8B ### PARENT POOL PROXY PRODUCTION CONTRACTS ADDRESSES ### PARENT_POOL_PROXY_BASE=0x0AE1B2730066AD46481ab0a5fd2B5893f8aBa323 @@ -50,7 +50,7 @@ PARENT_POOL_PROXY_BASE=0x0AE1B2730066AD46481ab0a5fd2B5893f8aBa323 PARENT_POOL_PROXY_ADMIN_BASE=0xF069f384a177083c4d62539e187860d2e163b0F4 ### PARENT POOL IMPLEMENTATION PRODUCTION CONTRACTS ADDRESSES ### -PARENT_POOL_BASE=0xF563fBd205f1930e4527Ee6d39512f2e2b6cE000 +PARENT_POOL_BASE=0x00ae866A88ED98582F796A4a9c5e8a472a3fDd29 PARENT_POOL_AUTOMATION_FORWARDER_BASE=0x15B457D85653A2cdebCd8E742bBCcADB1691bc2A @@ -71,3 +71,5 @@ CONCERO_PAUSE_ARBITRUM=0x00c4d25487297C4fc1341aa840a4F56e474f6A0d CONCERO_PAUSE_POLYGON=0x00c4d25487297C4fc1341aa840a4F56e474f6A0d CONCERO_PAUSE_BASE=0x00c4d25487297C4fc1341aa840a4F56e474f6A0d CONCERO_PAUSE_AVALANCHE=0x00c4d25487297C4fc1341aa840a4F56e474f6A0d + +PARENT_POOL_CLF_CLA_BASE=0x9015c8E94D168b4DF96aC189Cd7b54F94B77C94F \ No newline at end of file diff --git a/constants/rpcUrls.ts b/constants/rpcUrls.ts index 5699c32a..df6d80c2 100644 --- a/constants/rpcUrls.ts +++ b/constants/rpcUrls.ts @@ -1,4 +1,5 @@ -const { INFURA_API_KEY, ALCHEMY_API_KEY, BLAST_API_KEY, CHAINSTACK_API_KEY, TENDERLY_API_KEY } = process.env; +const { INFURA_API_KEY, DRPC_API_KEY, ALCHEMY_API_KEY, BLAST_API_KEY, CHAINSTACK_API_KEY, TENDERLY_API_KEY } = + process.env; export const rpc: Record = { arbitrum: `https://arbitrum-mainnet.infura.io/v3/${INFURA_API_KEY}`, @@ -19,47 +20,55 @@ export const rpc: Record = { export const urls: Record = { mainnet: [ + `https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_API_KEY}`, `https://mainnet.infura.io/v3/${INFURA_API_KEY}`, `https://eth-mainnet.blastapi.io/${BLAST_API_KEY}`, "https://rpc.ankr.com/eth", ], sepolia: [ + `https://lb.drpc.org/ogrpc?network=sepolia&dkey=${DRPC_API_KEY}`, `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, `https://eth-sepolia.blastapi.io/${BLAST_API_KEY}`, "https://rpc.ankr.com/eth_sepolia", ], avalanche: [ - `https://ava-mainnet.public.blastapi.io/ext/bc/C/rpc/${BLAST_API_KEY}`, + `https://lb.drpc.org/ogrpc?network=avalanche&dkey=${DRPC_API_KEY}`, + `https://ava-mainnet.blastapi.io/${BLAST_API_KEY}ext/bc/C/rpc`, "https://rpc.ankr.com/avalanche", `https://avalanche-mainnet.infura.io/v3/${INFURA_API_KEY}`, ], avalancheFuji: [ - "https://rpc.ankr.com/avalanche_fuji", + `https://lb.drpc.org/ogrpc?network=avalanche-fuji&dkey=${DRPC_API_KEY}`, `https://avalanche-fuji.infura.io/v3/${INFURA_API_KEY}`, `https://avalanche-fuji.core.chainstack.com/ext/bc/C/rpc/${CHAINSTACK_API_KEY}`, - `https://ava-testnet.blastapi.io/${BLAST_API_KEY}`, + `https://ava-testnet.blastapi.io/${BLAST_API_KEY}ext/bc/C/rpc`, ], arbitrum: [ + `https://lb.drpc.org/ogrpc?network=arbitrum&dkey=${DRPC_API_KEY}`, `https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, `https://arbitrum-one.blastapi.io/${BLAST_API_KEY}`, "https://rpc.ankr.com/arbitrum", ], arbitrumSepolia: [ + `https://lb.drpc.org/ogrpc?network=arbitrum-sepolia&dkey=${DRPC_API_KEY}`, `https://arbitrum-sepolia.infura.io/v3/${INFURA_API_KEY}`, `https://arbitrum-sepolia.blastapi.io/${BLAST_API_KEY}`, "https://rpc.ankr.com/arbitrum_sepolia", ], optimism: [ + `https://lb.drpc.org/ogrpc?network=optimism&dkey=${DRPC_API_KEY}`, `https://optimism-mainnet.infura.io/v3/${INFURA_API_KEY}`, `https://optimism-mainnet.blastapi.io/${BLAST_API_KEY}`, "https://rpc.ankr.com/optimism", ], optimismSepolia: [ + `https://lb.drpc.org/ogrpc?network=optimism-sepolia&dkey=${DRPC_API_KEY}`, `https://optimism-sepolia.infura.io/v3/${INFURA_API_KEY}`, `https://optimism-sepolia.blastapi.io/${BLAST_API_KEY}`, "https://rpc.ankr.com/optimism_sepolia", ], polygon: [ + `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", @@ -67,17 +76,21 @@ export const urls: Record = { "https://polygon-bor-rpc.publicnode.com", ], polygonAmoy: [ - "https://rpc.ankr.com/polygon_amoy", + `https://lb.drpc.org/ogrpc?network=polygon-amoy&dkey=${DRPC_API_KEY}`, `https://polygon-amoy.blastapi.io/${BLAST_API_KEY}`, `https://polygon-amoy.infura.io/v3/${INFURA_API_KEY}`, ], base: [ + `https://lb.drpc.org/ogrpc?network=base&dkey=${DRPC_API_KEY}`, + "https://base.llamarpc.com", + "https://base.blockpi.network/v1/rpc/public", `https://base-mainnet.infura.io/v3/${INFURA_API_KEY}`, - // "https://rpc.ankr.com/base", - // `https://base-rpc.publicnode.com`, - // `https://base-mainnet.blastapi.io/${BLAST_API_KEY}`, + `https://base-rpc.publicnode.com`, + "https://rpc.ankr.com/base", + `https://base-mainnet.blastapi.io/${BLAST_API_KEY}`, ], baseSepolia: [ + `https://lb.drpc.org/ogrpc?network=base-sepolia&dkey=${DRPC_API_KEY}`, `https://base-sepolia.infura.io/v3/${INFURA_API_KEY}`, `https://base-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, "https://rpc.ankr.com/base_sepolia", diff --git a/contracts/ParentPool.sol b/contracts/ParentPool.sol index 10e62821..57579335 100644 --- a/contracts/ParentPool.sol +++ b/contracts/ParentPool.sol @@ -130,6 +130,10 @@ contract ParentPool is IParentPool, CCIPReceiver, ParentPoolCommon, ParentPoolSt return s_withdrawalRequestIds; } + function getLiquidityCap() external view returns (uint256) { + return s_liquidityCap; + } + function handleOracleFulfillment( bytes32 requestId, bytes memory delegateCallResponse, diff --git a/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.js b/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.js index 414bbf77..20df803f 100644 --- a/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.js +++ b/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.js @@ -1,19 +1,31 @@ (async () => { const chainSelectors = { - ['3478487238524512106']: { - urls: [`https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`], - chainId: '0x66eee', - usdcAddress: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d', - poolAddress: '0x08b7325A4fF82F97803ff650A3288E036FB424ea', + ['4949039107694359620']: { + urls: [`https://arbitrum-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], + chainId: '0xa4b1', + usdcAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + poolAddress: '0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d', }, - ['10344971235874465080']: { - urls: [`https://base-sepolia.g.alchemy.com/v2/${secrets.ALCHEMY_API_KEY}`], - chainId: '0x14a34', - usdcAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', - poolAddress: '0xD5B19458Ddd36f75Cb8309B0e3bfB607Ccc04EB6', + ['4051577828743386545']: { + urls: [`https://polygon-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], + chainId: '0x89', + usdcAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', + poolAddress: '0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d', + }, + ['6433500567565415381']: { + urls: [`https://avalanche-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], + chainId: '0xa86a', + usdcAddress: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', + poolAddress: '0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d', + }, + ['15971525489660198786']: { + urls: [`https://base-mainnet.g.alchemy.com/v2/${secrets.PARENT_POOL_ALCHEMY_API_KEY}`], + chainId: '0x2105', + usdcAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + poolAddress: '0x0AE1B2730066AD46481ab0a5fd2B5893f8aBa323', }, }; - const baseChainSelector = '10344971235874465080'; + const baseChainSelector = '15971525489660198786'; const erc20Abi = ['function balanceOf(address) external view returns (uint256)']; const poolAbi = [ 'function s_loansInUse() external view returns (uint256)', diff --git a/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.min.js b/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.min.js index c48110af..2b769d91 100644 --- a/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.min.js +++ b/tasks/CLFScripts/dist/pool/getChildPoolsLiquidity.min.js @@ -1 +1 @@ -(async()=>{const chainSelectors={['3478487238524512106']:{urls:[`https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`],chainId:'0x66eee',usdcAddress:'0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d',poolAddress:'0x08b7325A4fF82F97803ff650A3288E036FB424ea',},['10344971235874465080']:{urls:[`https://base-sepolia.g.alchemy.com/v2/${secrets.ALCHEMY_API_KEY}`],chainId:'0x14a34',usdcAddress:'0x036CbD53842c5426634e7929541eC2318f3dCF7e',poolAddress:'0xD5B19458Ddd36f75Cb8309B0e3bfB607Ccc04EB6',},};const baseChainSelector='10344971235874465080';const erc20Abi=['function balanceOf(address)external view returns(uint256)'];const poolAbi=[ 'function s_loansInUse()external view returns(uint256)','function getDepositsOnTheWay()external view returns(tuple(uint64,bytes32,uint256)[150] memory)',];const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));const findChainIdByUrl=url=>{for(const chain in chainSelectors){if(chainSelectors[chain].urls.includes(url))return chainSelectors[chain].chainId;}return null;};class FunctionsJsonRpcProvider extends ethers.JsonRpcProvider{constructor(url){super(url);this.url=url;}async _send(payload){if(payload.method==='eth_chainId'){const _chainId=findChainIdByUrl(this.url);return [{jsonrpc:'2.0',id:payload.id,result:_chainId}];}const resp=await fetch(this.url,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload),});const res=await resp.json();if(res.length===undefined)return [res];return res.map((r,i)=>{return{jsonrpc:'2.0',id:payload[i].id,result:r.result};});}}const getProviderByChainSelector=_chainSelector=>{const urls=chainSelectors[_chainSelector].urls;const url=urls[Math.floor(Math.random()*urls.length)];return new FunctionsJsonRpcProvider(url);};const baseProvider=getProviderByChainSelector(baseChainSelector);const getBaseDepositsOneTheWayArray=()=>{const pool=new ethers.Contract(chainSelectors[baseChainSelector].poolAddress,poolAbi,baseProvider);return pool.getDepositsOnTheWay();};const getChildPoolsCcipLogs=async ccipLines=>{const ethersId=ethers.id('CCIPReceived(bytes32,uint64,address,address,uint256)');const indexes={};const getCcipLogs=async()=>{const promises=[];for(const chainSelectorsKey in chainSelectors){const reqFromLines=ccipLines.filter(line=>BigInt(line.chainSelector)===BigInt(chainSelectorsKey));if(!reqFromLines.length)continue;const provider=getProviderByChainSelector(chainSelectorsKey);if(!indexes[chainSelectorsKey]){indexes[chainSelectorsKey]=0;}let i=indexes[chainSelectorsKey];for(;i{if(!logs?.length)return [];const conceroIds=[];for(const log of logs){if(!log.length)continue;const ccipMessageId=log[0].topics[1];const ccipLine=ccipLines.find(line=>line.ccipMessageId.toLowerCase()===ccipMessageId.toLowerCase());conceroIds.push(ccipLine.index);}return conceroIds;};const packResult=(_totalBalance,_conceroIds)=>{const result=new Uint8Array(32+_conceroIds.length);const encodedTotalBalance=Functions.encodeUint256(_totalBalance);result.set(encodedTotalBalance,0);for(let i=0;i<_conceroIds.length;i++){const encodedConceroId=new Uint8Array([Number(_conceroIds[i])]);result.set(encodedConceroId,32+i);}return result;};let promises=[];let totalBalance=0n;for(const chain in chainSelectors){if(chain.toLowerCase()===baseChainSelector.toLowerCase())continue;const provider=getProviderByChainSelector(chain);const erc20=new ethers.Contract(chainSelectors[chain].usdcAddress,erc20Abi,provider);const pool=new ethers.Contract(chainSelectors[chain].poolAddress,poolAbi,provider);promises.push(erc20.balanceOf(chainSelectors[chain].poolAddress));promises.push(pool.s_loansInUse());}promises.push(getBaseDepositsOneTheWayArray());const results=await Promise.all(promises);for(let i=0;i{if(ccipMessageId !=='0x0000000000000000000000000000000000000000000000000000000000000000'){acc.push({index,chainSelector,ccipMessageId,amount});}return acc;},[]);let conceroIds=[];if(depositsOnTheWay.length){const logs=await getChildPoolsCcipLogs(depositsOnTheWay);conceroIds=getCompletedConceroIdsByLogs(logs,depositsOnTheWay);}return packResult(totalBalance,conceroIds);})(); \ No newline at end of file +(async()=>{const chainSelectors={['4949039107694359620']:{urls:[`https://arbitrum-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`],chainId:'0xa4b1',usdcAddress:'0xaf88d065e77c8cC2239327C5EDb3A432268e5831',poolAddress:'0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d',},['4051577828743386545']:{urls:[`https://polygon-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`],chainId:'0x89',usdcAddress:'0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',poolAddress:'0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d',},['6433500567565415381']:{urls:[`https://avalanche-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`],chainId:'0xa86a',usdcAddress:'0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',poolAddress:'0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d',},['15971525489660198786']:{urls:[`https://base-mainnet.g.alchemy.com/v2/${secrets.PARENT_POOL_ALCHEMY_API_KEY}`],chainId:'0x2105',usdcAddress:'0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',poolAddress:'0x0AE1B2730066AD46481ab0a5fd2B5893f8aBa323',},};const baseChainSelector='15971525489660198786';const erc20Abi=['function balanceOf(address)external view returns(uint256)'];const poolAbi=[ 'function s_loansInUse()external view returns(uint256)','function getDepositsOnTheWay()external view returns(tuple(uint64,bytes32,uint256)[150] memory)',];const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));const findChainIdByUrl=url=>{for(const chain in chainSelectors){if(chainSelectors[chain].urls.includes(url))return chainSelectors[chain].chainId;}return null;};class FunctionsJsonRpcProvider extends ethers.JsonRpcProvider{constructor(url){super(url);this.url=url;}async _send(payload){if(payload.method==='eth_chainId'){const _chainId=findChainIdByUrl(this.url);return [{jsonrpc:'2.0',id:payload.id,result:_chainId}];}const resp=await fetch(this.url,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload),});const res=await resp.json();if(res.length===undefined)return [res];return res.map((r,i)=>{return{jsonrpc:'2.0',id:payload[i].id,result:r.result};});}}const getProviderByChainSelector=_chainSelector=>{const urls=chainSelectors[_chainSelector].urls;const url=urls[Math.floor(Math.random()*urls.length)];return new FunctionsJsonRpcProvider(url);};const baseProvider=getProviderByChainSelector(baseChainSelector);const getBaseDepositsOneTheWayArray=()=>{const pool=new ethers.Contract(chainSelectors[baseChainSelector].poolAddress,poolAbi,baseProvider);return pool.getDepositsOnTheWay();};const getChildPoolsCcipLogs=async ccipLines=>{const ethersId=ethers.id('CCIPReceived(bytes32,uint64,address,address,uint256)');const indexes={};const getCcipLogs=async()=>{const promises=[];for(const chainSelectorsKey in chainSelectors){const reqFromLines=ccipLines.filter(line=>BigInt(line.chainSelector)===BigInt(chainSelectorsKey));if(!reqFromLines.length)continue;const provider=getProviderByChainSelector(chainSelectorsKey);if(!indexes[chainSelectorsKey]){indexes[chainSelectorsKey]=0;}let i=indexes[chainSelectorsKey];for(;i{if(!logs?.length)return [];const conceroIds=[];for(const log of logs){if(!log.length)continue;const ccipMessageId=log[0].topics[1];const ccipLine=ccipLines.find(line=>line.ccipMessageId.toLowerCase()===ccipMessageId.toLowerCase());conceroIds.push(ccipLine.index);}return conceroIds;};const packResult=(_totalBalance,_conceroIds)=>{const result=new Uint8Array(32+_conceroIds.length);const encodedTotalBalance=Functions.encodeUint256(_totalBalance);result.set(encodedTotalBalance,0);for(let i=0;i<_conceroIds.length;i++){const encodedConceroId=new Uint8Array([Number(_conceroIds[i])]);result.set(encodedConceroId,32+i);}return result;};let promises=[];let totalBalance=0n;for(const chain in chainSelectors){if(chain.toLowerCase()===baseChainSelector.toLowerCase())continue;const provider=getProviderByChainSelector(chain);const erc20=new ethers.Contract(chainSelectors[chain].usdcAddress,erc20Abi,provider);const pool=new ethers.Contract(chainSelectors[chain].poolAddress,poolAbi,provider);promises.push(erc20.balanceOf(chainSelectors[chain].poolAddress));promises.push(pool.s_loansInUse());}promises.push(getBaseDepositsOneTheWayArray());const results=await Promise.all(promises);for(let i=0;i{if(ccipMessageId !=='0x0000000000000000000000000000000000000000000000000000000000000000'){acc.push({index,chainSelector,ccipMessageId,amount});}return acc;},[]);let conceroIds=[];if(depositsOnTheWay.length){const logs=await getChildPoolsCcipLogs(depositsOnTheWay);conceroIds=getCompletedConceroIdsByLogs(logs,depositsOnTheWay);}return packResult(totalBalance,conceroIds);})(); \ No newline at end of file diff --git a/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.js b/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.js index 6ecbe287..5ec6b4fb 100644 --- a/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.js +++ b/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.js @@ -2,15 +2,35 @@ try { const [_, __, ___, liquidityRequestedFromEachPool, withdrawalId] = bytesArgs; const chainSelectors = { - [`0x${BigInt('3478487238524512106').toString(16)}`]: { + [`0x${BigInt('4949039107694359620').toString(16)}`]: { urls: [ - `https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`, - 'https://arbitrum-sepolia.blockpi.network/v1/rpc/public', - 'https://arbitrum-sepolia-rpc.publicnode.com', + `https://arbitrum-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, + 'https://arbitrum.blockpi.network/v1/rpc/public', + 'https://arbitrum-rpc.publicnode.com', ], - chainId: '0x66eee', - usdcAddress: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d', - poolAddress: '0x08b7325A4fF82F97803ff650A3288E036FB424ea', + chainId: '0xa4b1', + usdcAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + poolAddress: '0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d', + }, + [`0x${BigInt('4051577828743386545').toString(16)}`]: { + urls: [ + `https://polygon-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, + 'https://polygon.blockpi.network/v1/rpc/public', + 'https://polygon-bor-rpc.publicnode.com', + ], + chainId: '0x89', + usdcAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', + poolAddress: '0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d', + }, + [`0x${BigInt('6433500567565415381').toString(16)}`]: { + urls: [ + `https://avalanche-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, + 'https://avalanche.blockpi.network/v1/rpc/public', + 'https://avalanche-c-chain-rpc.publicnode.com', + ], + chainId: '0xa86a', + usdcAddress: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', + poolAddress: '0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d', }, }; const getChainIdByUrl = url => { @@ -19,7 +39,7 @@ } return null; }; - const baseChainSelector = `0x${BigInt('10344971235874465080').toString(16)}`; + const baseChainSelector = `0x${BigInt('15971525489660198786').toString(16)}`; class FunctionsJsonRpcProvider extends ethers.JsonRpcProvider { constructor(url) { super(url); diff --git a/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.min.js b/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.min.js index e06dd993..8dbf9367 100644 --- a/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.min.js +++ b/tasks/CLFScripts/dist/pool/withdrawalLiquidityCollection.min.js @@ -1 +1 @@ -(async()=>{try{const [_,__,___,liquidityRequestedFromEachPool,withdrawalId]=bytesArgs;const chainSelectors={[`0x${BigInt('3478487238524512106').toString(16)}`]:{urls:[ `https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://arbitrum-sepolia.blockpi.network/v1/rpc/public','https://arbitrum-sepolia-rpc.publicnode.com',],chainId:'0x66eee',usdcAddress:'0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d',poolAddress:'0x08b7325A4fF82F97803ff650A3288E036FB424ea',},};const getChainIdByUrl=url=>{for(const chain in chainSelectors){if(chainSelectors[chain].urls.includes(url))return chainSelectors[chain].chainId;}return null;};const baseChainSelector=`0x${BigInt('10344971235874465080').toString(16)}`;class FunctionsJsonRpcProvider extends ethers.JsonRpcProvider{constructor(url){super(url);this.url=url;}async _send(payload){if(payload.method==='eth_estimateGas'){return [{jsonrpc:'2.0',id:payload.id,result:'0x1e8480'}];}if(payload.method==='eth_chainId'){const _chainId=getChainIdByUrl(this.url);return [{jsonrpc:'2.0',id:payload.id,result:_chainId}];}let resp=await fetch(this.url,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload),});const res=await resp.json();if(res.length===undefined)return [res];return res;}}const poolAbi=['function ccipSendToPool(uint64,uint256,bytes32)external'];const promises=[];for(const chainSelector in chainSelectors){const url=chainSelectors[chainSelector].urls[Math.floor(Math.random()*chainSelectors[chainSelector].urls.length)];const provider=new FunctionsJsonRpcProvider(url);const wallet=new ethers.Wallet('0x'+secrets.POOL_MESSENGER_0_PRIVATE_KEY,provider);const signer=wallet.connect(provider);const poolContract=new ethers.Contract(chainSelectors[chainSelector].poolAddress,poolAbi,signer);promises.push(poolContract.ccipSendToPool(baseChainSelector,liquidityRequestedFromEachPool,withdrawalId));}await Promise.all(promises);return Functions.encodeUint256(1n);}catch(e){const{message,code}=e;if(code==='NONCE_EXPIRED' || message?.includes('replacement fee too low')|| message?.includes('already known')){return Functions.encodeUint256(1n);}throw e;}})(); \ No newline at end of file +(async()=>{try{const [_,__,___,liquidityRequestedFromEachPool,withdrawalId]=bytesArgs;const chainSelectors={[`0x${BigInt('4949039107694359620').toString(16)}`]:{urls:[ `https://arbitrum-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://arbitrum.blockpi.network/v1/rpc/public','https://arbitrum-rpc.publicnode.com',],chainId:'0xa4b1',usdcAddress:'0xaf88d065e77c8cC2239327C5EDb3A432268e5831',poolAddress:'0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d',},[`0x${BigInt('4051577828743386545').toString(16)}`]:{urls:[ `https://polygon-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://polygon.blockpi.network/v1/rpc/public','https://polygon-bor-rpc.publicnode.com',],chainId:'0x89',usdcAddress:'0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',poolAddress:'0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d',},[`0x${BigInt('6433500567565415381').toString(16)}`]:{urls:[ `https://avalanche-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://avalanche.blockpi.network/v1/rpc/public','https://avalanche-c-chain-rpc.publicnode.com',],chainId:'0xa86a',usdcAddress:'0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',poolAddress:'0x164c20A4E11cBE0d8B5e23F5EE35675890BE280d',},};const getChainIdByUrl=url=>{for(const chain in chainSelectors){if(chainSelectors[chain].urls.includes(url))return chainSelectors[chain].chainId;}return null;};const baseChainSelector=`0x${BigInt('15971525489660198786').toString(16)}`;class FunctionsJsonRpcProvider extends ethers.JsonRpcProvider{constructor(url){super(url);this.url=url;}async _send(payload){if(payload.method==='eth_estimateGas'){return [{jsonrpc:'2.0',id:payload.id,result:'0x1e8480'}];}if(payload.method==='eth_chainId'){const _chainId=getChainIdByUrl(this.url);return [{jsonrpc:'2.0',id:payload.id,result:_chainId}];}let resp=await fetch(this.url,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload),});const res=await resp.json();if(res.length===undefined)return [res];return res;}}const poolAbi=['function ccipSendToPool(uint64,uint256,bytes32)external'];const promises=[];for(const chainSelector in chainSelectors){const url=chainSelectors[chainSelector].urls[Math.floor(Math.random()*chainSelectors[chainSelector].urls.length)];const provider=new FunctionsJsonRpcProvider(url);const wallet=new ethers.Wallet('0x'+secrets.POOL_MESSENGER_0_PRIVATE_KEY,provider);const signer=wallet.connect(provider);const poolContract=new ethers.Contract(chainSelectors[chainSelector].poolAddress,poolAbi,signer);promises.push(poolContract.ccipSendToPool(baseChainSelector,liquidityRequestedFromEachPool,withdrawalId));}await Promise.all(promises);return Functions.encodeUint256(1n);}catch(e){const{message,code}=e;if(code==='NONCE_EXPIRED' || message?.includes('replacement fee too low')|| message?.includes('already known')){return Functions.encodeUint256(1n);}throw e;}})(); \ No newline at end of file diff --git a/tasks/CLFScripts/src/pool/getChildPoolsLiquidity.js b/tasks/CLFScripts/src/pool/getChildPoolsLiquidity.js index e3aacb56..69428d2e 100644 --- a/tasks/CLFScripts/src/pool/getChildPoolsLiquidity.js +++ b/tasks/CLFScripts/src/pool/getChildPoolsLiquidity.js @@ -1,11 +1,11 @@ (async () => { const chainSelectors = { - ['${CL_CCIP_CHAIN_SELECTOR_ARBITRUM_SEPOLIA}']: { - urls: [`https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`], - chainId: '0x66eee', - usdcAddress: '${USDC_ARBITRUM_SEPOLIA}', - poolAddress: '${CHILD_POOL_PROXY_ARBITRUM_SEPOLIA}', - }, + // ['${CL_CCIP_CHAIN_SELECTOR_ARBITRUM_SEPOLIA}']: { + // urls: [`https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`], + // chainId: '0x66eee', + // usdcAddress: '${USDC_ARBITRUM_SEPOLIA}', + // poolAddress: '${CHILD_POOL_PROXY_ARBITRUM_SEPOLIA}', + // }, // ['${CL_CCIP_CHAIN_SELECTOR_FUJI}']: { // urls: [`https://avalanche-fuji.infura.io/v3/${secrets.INFURA_API_KEY}`], @@ -13,43 +13,43 @@ // usdcAddress: '${USDC_FUJI}', // poolAddress: '${CHILD_POOL_PROXY_FUJI}', // }, - - ['${CL_CCIP_CHAIN_SELECTOR_BASE_SEPOLIA}']: { - urls: [`https://base-sepolia.g.alchemy.com/v2/${secrets.ALCHEMY_API_KEY}`], - chainId: '0x14a34', - usdcAddress: '${USDC_BASE_SEPOLIA}', - poolAddress: '${PARENT_POOL_PROXY_BASE_SEPOLIA}', - }, + // + // ['${CL_CCIP_CHAIN_SELECTOR_BASE_SEPOLIA}']: { + // urls: [`https://base-sepolia.g.alchemy.com/v2/${secrets.ALCHEMY_API_KEY}`], + // chainId: '0x14a34', + // usdcAddress: '${USDC_BASE_SEPOLIA}', + // poolAddress: '${PARENT_POOL_PROXY_BASE_SEPOLIA}', + // }, // mainnets - // ['${CL_CCIP_CHAIN_SELECTOR_ARBITRUM}']: { - // urls: [`https://arbitrum-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], - // chainId: '0xa4b1', - // usdcAddress: '${USDC_ARBITRUM}', - // poolAddress: '${CHILD_POOL_PROXY_ARBITRUM}', - // }, - // ['${CL_CCIP_CHAIN_SELECTOR_POLYGON}']: { - // urls: [`https://polygon-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], - // chainId: '0x89', - // usdcAddress: '${USDC_POLYGON}', - // poolAddress: '${CHILD_POOL_PROXY_POLYGON}', - // }, - // ['${CL_CCIP_CHAIN_SELECTOR_AVALANCHE}']: { - // urls: [`https://avalanche-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], - // chainId: '0xa86a', - // usdcAddress: '${USDC_AVALANCHE}', - // poolAddress: '${CHILD_POOL_PROXY_AVALANCHE}', - // }, - // ['${CL_CCIP_CHAIN_SELECTOR_BASE}']: { - // urls: [`https://base-mainnet.g.alchemy.com/v2/${secrets.PARENT_POOL_ALCHEMY_API_KEY}`], - // chainId: '0x2105', - // usdcAddress: '${USDC_BASE}', - // poolAddress: '${PARENT_POOL_PROXY_BASE}', - // }, + ['${CL_CCIP_CHAIN_SELECTOR_ARBITRUM}']: { + urls: [`https://arbitrum-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], + chainId: '0xa4b1', + usdcAddress: '${USDC_ARBITRUM}', + poolAddress: '${CHILD_POOL_PROXY_ARBITRUM}', + }, + ['${CL_CCIP_CHAIN_SELECTOR_POLYGON}']: { + urls: [`https://polygon-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], + chainId: '0x89', + usdcAddress: '${USDC_POLYGON}', + poolAddress: '${CHILD_POOL_PROXY_POLYGON}', + }, + ['${CL_CCIP_CHAIN_SELECTOR_AVALANCHE}']: { + urls: [`https://avalanche-mainnet.infura.io/v3/${secrets.PARENT_POOL_INFURA_API_KEY}`], + chainId: '0xa86a', + usdcAddress: '${USDC_AVALANCHE}', + poolAddress: '${CHILD_POOL_PROXY_AVALANCHE}', + }, + ['${CL_CCIP_CHAIN_SELECTOR_BASE}']: { + urls: [`https://base-mainnet.g.alchemy.com/v2/${secrets.PARENT_POOL_ALCHEMY_API_KEY}`], + chainId: '0x2105', + usdcAddress: '${USDC_BASE}', + poolAddress: '${PARENT_POOL_PROXY_BASE}', + }, }; - // const baseChainSelector = '${CL_CCIP_CHAIN_SELECTOR_BASE}'; - const baseChainSelector = '${CL_CCIP_CHAIN_SELECTOR_BASE_SEPOLIA}'; + const baseChainSelector = '${CL_CCIP_CHAIN_SELECTOR_BASE}'; + // const baseChainSelector = '${CL_CCIP_CHAIN_SELECTOR_BASE_SEPOLIA}'; const erc20Abi = ['function balanceOf(address) external view returns (uint256)']; const poolAbi = [ 'function s_loansInUse() external view returns (uint256)', diff --git a/tasks/CLFScripts/src/pool/withdrawalLiquidityCollection.js b/tasks/CLFScripts/src/pool/withdrawalLiquidityCollection.js index de4e56b3..cc99b6fe 100644 --- a/tasks/CLFScripts/src/pool/withdrawalLiquidityCollection.js +++ b/tasks/CLFScripts/src/pool/withdrawalLiquidityCollection.js @@ -3,16 +3,16 @@ const [_, __, ___, liquidityRequestedFromEachPool, withdrawalId] = bytesArgs; const chainSelectors = { - [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_ARBITRUM_SEPOLIA}').toString(16)}`]: { - urls: [ - `https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`, - 'https://arbitrum-sepolia.blockpi.network/v1/rpc/public', - 'https://arbitrum-sepolia-rpc.publicnode.com', - ], - chainId: '0x66eee', - usdcAddress: '${USDC_ARBITRUM_SEPOLIA}', - poolAddress: '${CHILD_POOL_PROXY_ARBITRUM_SEPOLIA}', - }, + // [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_ARBITRUM_SEPOLIA}').toString(16)}`]: { + // urls: [ + // `https://arbitrum-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`, + // 'https://arbitrum-sepolia.blockpi.network/v1/rpc/public', + // 'https://arbitrum-sepolia-rpc.publicnode.com', + // ], + // chainId: '0x66eee', + // usdcAddress: '${USDC_ARBITRUM_SEPOLIA}', + // poolAddress: '${CHILD_POOL_PROXY_ARBITRUM_SEPOLIA}', + // }, // [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_FUJI}').toString(16)}`]: { // urls: [ // `https://avalanche-fuji.infura.io/v3/${secrets.INFURA_API_KEY}`, @@ -23,38 +23,37 @@ // usdcAddress: '${USDC_FUJI}', // poolAddress: '${CHILD_POOL_PROXY_FUJI}', // }, - // mainnets - // [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_ARBITRUM}').toString(16)}`]: { - // urls: [ - // `https://arbitrum-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, - // 'https://arbitrum.blockpi.network/v1/rpc/public', - // 'https://arbitrum-rpc.publicnode.com', - // ], - // chainId: '0xa4b1', - // usdcAddress: '${USDC_ARBITRUM}', - // poolAddress: '${CHILD_POOL_PROXY_ARBITRUM}', - // }, - // [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_POLYGON}').toString(16)}`]: { - // urls: [ - // `https://polygon-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, - // 'https://polygon.blockpi.network/v1/rpc/public', - // 'https://polygon-bor-rpc.publicnode.com', - // ], - // chainId: '0x89', - // usdcAddress: '${USDC_POLYGON}', - // poolAddress: '${CHILD_POOL_PROXY_POLYGON}', - // }, - // [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_AVALANCHE}').toString(16)}`]: { - // urls: [ - // `https://avalanche-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, - // 'https://avalanche.blockpi.network/v1/rpc/public', - // 'https://avalanche-c-chain-rpc.publicnode.com', - // ], - // chainId: '0xa86a', - // usdcAddress: '${USDC_AVALANCHE}', - // poolAddress: '${CHILD_POOL_PROXY_AVALANCHE}', - // }, + [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_ARBITRUM}').toString(16)}`]: { + urls: [ + `https://arbitrum-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, + 'https://arbitrum.blockpi.network/v1/rpc/public', + 'https://arbitrum-rpc.publicnode.com', + ], + chainId: '0xa4b1', + usdcAddress: '${USDC_ARBITRUM}', + poolAddress: '${CHILD_POOL_PROXY_ARBITRUM}', + }, + [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_POLYGON}').toString(16)}`]: { + urls: [ + `https://polygon-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, + 'https://polygon.blockpi.network/v1/rpc/public', + 'https://polygon-bor-rpc.publicnode.com', + ], + chainId: '0x89', + usdcAddress: '${USDC_POLYGON}', + poolAddress: '${CHILD_POOL_PROXY_POLYGON}', + }, + [`0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_AVALANCHE}').toString(16)}`]: { + urls: [ + `https://avalanche-mainnet.infura.io/v3/${secrets.INFURA_API_KEY}`, + 'https://avalanche.blockpi.network/v1/rpc/public', + 'https://avalanche-c-chain-rpc.publicnode.com', + ], + chainId: '0xa86a', + usdcAddress: '${USDC_AVALANCHE}', + poolAddress: '${CHILD_POOL_PROXY_AVALANCHE}', + }, }; const getChainIdByUrl = url => { @@ -64,8 +63,8 @@ return null; }; - // const baseChainSelector = `0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_BASE}').toString(16)}`; - const baseChainSelector = `0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_BASE_SEPOLIA}').toString(16)}`; + const baseChainSelector = `0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_BASE}').toString(16)}`; + // const baseChainSelector = `0x${BigInt('${CL_CCIP_CHAIN_SELECTOR_BASE_SEPOLIA}').toString(16)}`; class FunctionsJsonRpcProvider extends ethers.JsonRpcProvider { constructor(url) { diff --git a/tasks/concero/checkRPCStatus.ts b/tasks/concero/checkRPCStatus.ts index 09c2c507..9f90aa3c 100644 --- a/tasks/concero/checkRPCStatus.ts +++ b/tasks/concero/checkRPCStatus.ts @@ -1,63 +1,132 @@ import { task } from "hardhat/config"; -import axios from "axios"; -import { conceroNetworks } from "../../constants"; -import { log } from "../../utils"; +import axios, { AxiosInstance } from "axios"; +import { setTimeout } from "timers/promises"; +import { urls as rpcUrls } from "../../constants"; -const request = { - jsonrpc: "2.0", - method: "eth_call", - params: [ - { - from: "", - to: "", - gas: "", - gasPrice: "", - value: "", - data: "", +const CONFIG = { + TIMEOUT_MS: 5000, + RETRY_ATTEMPTS: 2, + RETRY_DELAY_MS: 1000, + CONCURRENT_REQUESTS: 10, + LOG_LEVEL: "info", // 'debug' | 'info' | 'error' +}; + +interface RpcResponse { + networkName: string; + url: string; + status: "OK" | "ERROR"; + latency: number; + errorMessage?: string; +} + +const createAxiosInstance = (): AxiosInstance => { + return axios.create({ + timeout: CONFIG.TIMEOUT_MS, + headers: { + "Content-Type": "application/json", }, - "latest", - ], + }); +}; + +const rpcRequest = { + jsonrpc: "2.0", + method: "eth_blockNumber", + params: [], id: 1, }; -export async function checkRpcStatus() { - for (const [name, chain] of Object.entries(conceroNetworks)) { - const urls = chain.urls; +async function checkSingleRpc( + networkName: string, + url: string, + axiosInstance: AxiosInstance, + attempt = 1, +): Promise { + const startTime = Date.now(); + try { + const response = await axiosInstance.post(url, rpcRequest); + const latency = Date.now() - startTime; - if (!urls || urls.length === 0) { - log(`\nRPCs healthcheck for network:`, "checkRPCStatus", name); - console.table([{ URL: "N/A", Status: "No URLs provided" }]); - continue; + if (response.data?.result) { + return { + networkName, + url: new URL(url).origin, + status: "OK", + latency, + }; + } + throw new Error("Invalid response format"); + } catch (error) { + if (attempt < CONFIG.RETRY_ATTEMPTS) { + await setTimeout(CONFIG.RETRY_DELAY_MS); + return checkSingleRpc(networkName, url, axiosInstance, attempt + 1); } - const results = await Promise.all( - urls.map(async url => { - try { - const response = await axios.post(url, request); - - const parsedUrl = new URL(url); - const shortenedUrl = parsedUrl.origin + "/"; - - if (response.status === 200) { - return { URL: shortenedUrl, Status: "OK" }; - } else { - return { URL: shortenedUrl, Status: `Error: ${response.status}` }; - } - } catch (error) { - const parsedUrl = new URL(url); - const shortenedUrl = parsedUrl.origin + "/"; - - return { URL: shortenedUrl, Status: `Error: ${error.message}` }; - } - }), - ); + return { + networkName, + url: new URL(url).origin, + status: "ERROR", + latency: Date.now() - startTime, + errorMessage: error.message, + }; + } +} - log(`RPCs healthcheck`, "checkRPCStatus", name); - console.table(results); +async function processBatch(batch: [string, string][], axiosInstance: AxiosInstance): Promise { + return Promise.all(batch.map(([networkName, url]) => checkSingleRpc(networkName, url, axiosInstance))); +} + +export async function checkRpcStatus() { + const axiosInstance = createAxiosInstance(); + const allChecks: [string, string][] = []; + + for (const [networkName, urls] of Object.entries(rpcUrls)) { + urls.forEach(url => { + allChecks.push([networkName, url]); + }); + } + + const results: RpcResponse[] = []; + for (let i = 0; i < allChecks.length; i += CONFIG.CONCURRENT_REQUESTS) { + const batch = allChecks.slice(i, i + CONFIG.CONCURRENT_REQUESTS); + const batchResults = await processBatch(batch, axiosInstance); + results.push(...batchResults); } + + const groupedResults = results.reduce( + (acc, result) => { + if (!acc[result.networkName]) { + acc[result.networkName] = []; + } + acc[result.networkName].push(result); + return acc; + }, + {} as Record, + ); + + Object.entries(groupedResults).forEach(([networkName, networkResults]) => { + console.log(`\n=== ${networkName.toUpperCase()} RPC Status ===`); + console.table( + networkResults.map(r => ({ + URL: r.url, + Status: r.status, + Latency: `${r.latency}ms`, + Error: r.errorMessage || "N/A", + })), + ); + }); + + const summary = { + total: results.length, + successful: results.filter(r => r.status === "OK").length, + failed: results.filter(r => r.status === "ERROR").length, + averageLatency: Math.round(results.reduce((acc, r) => acc + r.latency, 0) / results.length), + }; + + console.log("\n=== Summary ==="); + console.table([summary]); } -task("check-rpc-status", "Outputs a table of RPC URLs with their statuses").setAction(async (taskArgs, hre) => { +task("check-rpc-status", "Check the status of all RPC endpoints").setAction(async (_, hre) => { await checkRpcStatus(); }); diff --git a/tasks/concero/index.ts b/tasks/concero/index.ts index eb31c73c..6ef4917d 100644 --- a/tasks/concero/index.ts +++ b/tasks/concero/index.ts @@ -30,6 +30,7 @@ import updateParentPoolHashesTask from "./pools/updateParentPoolHashesTask"; import removeParentPoolChildPoolsTask from "./pools/removeParentPoolChildPoolsTask"; import updateInfraHashesTask from "./deployInfra/updateInfraHashesTask"; import { getWithdrawalStatuses } from "./getWithdrawalStatuses"; +import populateWithdrawalRequests from "./populateWithdrawalRequests"; export default { deployConceroDexSwap, deployConceroOrchestrator, @@ -60,4 +61,5 @@ export default { removeParentPoolChildPoolsTask, updateInfraHashesTask, getWithdrawalStatuses, + populateWithdrawalRequests, }; diff --git a/tasks/concero/populateWithdrawalRequests.ts b/tasks/concero/populateWithdrawalRequests.ts index cef8b0cd..e28aacef 100644 --- a/tasks/concero/populateWithdrawalRequests.ts +++ b/tasks/concero/populateWithdrawalRequests.ts @@ -1,5 +1,5 @@ import { task } from "hardhat/config"; -import log, { getClients, getEnvVar } from "../../utils"; +import { log, getClients, getEnvVar } from "../../utils"; import { conceroNetworks, networkEnvKeys } from "../../constants"; import fs from "fs"; @@ -8,9 +8,9 @@ task("populate-withdrawal-requests", "Reads withdrawal statuses from JSON and up const chain = conceroNetworks.base; try { const { publicClient, walletClient, account } = getClients(chain.name, chain.url); - const contractAddress = getEnvVar(`CONCERO_AUTOMATION_${networkEnvKeys[chain.name]}`); - console.log(contractAddress); - const { abi: claAbi } = await import("../../artifacts/contracts/ConceroAutomation.sol/ConceroAutomation.json"); + const contractAddress = getEnvVar(`PARENT_POOL_PROXY_${networkEnvKeys[chain.name]}`); + + const { abi: parentPoolAbi } = await import("../../artifacts/contracts/ParentPool.sol/ParentPool.json"); // Read JSON file const jsonData = fs.readFileSync("withdrawal-statuses.json", "utf8"); @@ -29,8 +29,8 @@ task("populate-withdrawal-requests", "Reads withdrawal statuses from JSON and up // Prepare transaction const { request } = await publicClient.simulateContract({ address: contractAddress, - abi: claAbi, - functionName: "addWithdrawRequests", + abi: parentPoolAbi, + functionName: "dev_addWithdrawalIds", args: [idChunk, triggeredChunk], account, chain: chain.viemChain,