From 3eae0ab4830dae09c85451a8aaec96bcacc739ae Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 13 Nov 2024 16:09:55 +0000 Subject: [PATCH 1/3] add husky pre-commit, clf simulate decoding --- package.json | 3 +- packages/foundry/Makefile | 2 +- .../hardhat/contracts/ParentPoolCLFCLA.sol | 2 +- packages/hardhat/package.json | 4 +- .../tasks/CLFScripts/decodeCLFResponse.ts | 50 ++++++++++ .../tasks/CLFScripts/dist/infra/SRC.js | 83 ++++++++--------- .../tasks/CLFScripts/dist/infra/SRC.min.js | 2 +- packages/hardhat/tasks/CLFScripts/simulate.ts | 12 ++- .../hardhat/tasks/CLFScripts/src/infra/SRC.js | 91 ++++++++++--------- 9 files changed, 155 insertions(+), 94 deletions(-) create mode 100644 packages/hardhat/tasks/CLFScripts/decodeCLFResponse.ts diff --git a/package.json b/package.json index cb98ae6ff..7ba752dc2 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,8 @@ "clf-sub-fund": "yarn workspace @se-2/hardhat clf-sub-fund", "clf-sub-consumer-add": "yarn workspace @se-2/hardhat clf-sub-consumer-add", "clf-sub-consumer-rm": "yarn workspace @se-2/hardhat clf-sub-consumer-rm", - "clf-sub-timeout-requests": "yarn workspace @se-2/hardhat clf-sub-timeout-requests" + "clf-sub-timeout-requests": "yarn workspace @se-2/hardhat clf-sub-timeout-requests", + "prepare": "husky" }, "devDependencies": { "husky": "^8.0.1", diff --git a/packages/foundry/Makefile b/packages/foundry/Makefile index fb396a045..d92cd5dc4 100644 --- a/packages/foundry/Makefile +++ b/packages/foundry/Makefile @@ -9,7 +9,7 @@ # - `make run_fork` : Run an anvil fork on the BASE_LOCAL_FORK_PORT using the base RPC URL. # - `make run_arb_fork` : Run an anvil fork on the ARB_LOCAL_FORK_PORT using the ARB RPC URL. # - `make test` : Run all tests using forge with any optional arguments specified in --args. -# For example: `make test --args="--match-test Deposit"` +# For example: `make test args="--match-test Deposit"` include .env.foundry include ../../.env diff --git a/packages/hardhat/contracts/ParentPoolCLFCLA.sol b/packages/hardhat/contracts/ParentPoolCLFCLA.sol index 66d781e40..31f02aa7c 100644 --- a/packages/hardhat/contracts/ParentPoolCLFCLA.sol +++ b/packages/hardhat/contracts/ParentPoolCLFCLA.sol @@ -250,7 +250,7 @@ contract ParentPoolCLFCLA is uint256 childPoolsLiquidity, bytes1[] memory depositsOnTheWayIdsToDelete ) = _decodeCLFResponse(response); - +5 request.childPoolsLiquiditySnapshot = childPoolsLiquidity; _deleteDepositsOnTheWayByIndexes(depositsOnTheWayIdsToDelete); diff --git a/packages/hardhat/package.json b/packages/hardhat/package.json index 7fcf9a40e..1e196d52f 100644 --- a/packages/hardhat/package.json +++ b/packages/hardhat/package.json @@ -40,7 +40,8 @@ "clf-sub-fund": "hardhat clf-sub-fund", "clf-sub-consumer-add": "hardhat clf-sub-consumer-add", "clf-sub-consumer-rm": "hardhat clf-sub-consumer-rm", - "clf-sub-timeout-requests": "hardhat clf-sub-timeout-requests" + "clf-sub-timeout-requests": "hardhat clf-sub-timeout-requests", + "prepare": "husky" }, "devDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", @@ -90,6 +91,7 @@ "envfile": "^7.1.0", "ethers": "6.12.1", "hardhat-docgen": "^1.3.0", + "husky": "^9.1.6", "qrcode": "^1.5.1", "readline": "^1.3.0", "regenerator-runtime": "^0.14.1", diff --git a/packages/hardhat/tasks/CLFScripts/decodeCLFResponse.ts b/packages/hardhat/tasks/CLFScripts/decodeCLFResponse.ts new file mode 100644 index 000000000..b70155e76 --- /dev/null +++ b/packages/hardhat/tasks/CLFScripts/decodeCLFResponse.ts @@ -0,0 +1,50 @@ +import {AbiParameter, decodeAbiParameters} from 'viem'; + +const responseDecoders: {[key: string]: AbiParameter[]} = { + infra_src: [ + {type: 'uint256', name: 'dstGasPrice'}, + {type: 'uint256', name: 'srcGasPrice'}, + {type: 'uint64', name: 'dstChainSelector'}, + {type: 'uint256', name: 'linkUsdcRate'}, + {type: 'uint256', name: 'nativeUsdcRate'}, + {type: 'uint256', name: 'linkNativeRate'}, + ], + infra_dst: [{type: 'uint256', name: 'messageId'}], + pool_get_total_balance: [ + {type: 'uint256', name: 'childPoolsLiquidity'}, + {type: 'bytes1[]', name: 'depositsOnTheWayIdsToDelete'}, + ], + pool_distribute_liq: [ + {type: 'uint256', name: 'childPoolsLiquidity'}, + {type: 'bytes1[]', name: 'depositsOnTheWayIdsToDelete'}, + ], +}; +/** + * Decodes the response hex string based on the script name. + * @param scriptName - The name of the script. + * @param responseHex - The hex string response to decode. + * @returns An object containing the decoded values. + */ +export function decodeCLFResponse(scriptName: string, responseHex: string): any { + const decoder = responseDecoders[scriptName]; + if (!decoder) { + console.error(`No decoder defined for script: ${scriptName}`); + return null; + } + + const responseData = responseHex.startsWith('0x') ? responseHex : '0x' + responseHex; + + try { + const decodedValues = decodeAbiParameters(decoder, responseData); + const result: Record = {}; + + decoder.forEach((param, index) => { + result[param.name || `param${index}`] = decodedValues[index]; + }); + + return result; + } catch (error) { + console.error('Failed to decode response:', error); + return null; + } +} diff --git a/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.js b/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.js index aaf22f920..d5765789e 100644 --- a/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.js +++ b/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.js @@ -1,55 +1,56 @@ -function hexString(data) { - if (typeof data === 'string' || data instanceof String) { - if ((data = data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/))) { - if (data[2].length % 2) { - throw new Error('Hex string length must be a multiple of 2.'); +(async () => { + function hexString(data) { + if (typeof data === 'string' || data instanceof String) { + if ((data = data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/))) { + if (data[2].length % 2) { + throw new Error('Hex string length must be a multiple of 2.'); + } + return data[2]; } - return data[2]; } + throw new Error('Data must be a hex string.'); } - throw new Error('Data must be a hex string.'); -} -function byteToString(b) { - return (b | 0x100).toString(16).slice(1); -} -function parseByte(data, i) { - return parseInt(data.substr(i, 2), 16); -} -function cdCompress(data) { - data = hexString(data); - var o = '0x', - z = 0, - y = 0, - i = 0, - c; - function pushByte(b) { - o += byteToString(((o.length < 4 * 2 + 2) * 0xff) ^ b); + function byteToString(b) { + return (b | 0x100).toString(16).slice(1); } - function rle(v, d) { - pushByte(0x00); - pushByte(d - 1 + v * 0x80); + function parseByte(data, i) { + return parseInt(data.substr(i, 2), 16); } - for (; i < data.length; i += 2) { - c = parseByte(data, i); - if (!c) { - if (y) rle(1, y), (y = 0); - if (++z === 0x80) rle(0, 0x80), (z = 0); - continue; + function cdCompress(data) { + data = hexString(data); + var o = '0x', + z = 0, + y = 0, + i = 0, + c; + function pushByte(b) { + o += byteToString(((o.length < 4 * 2 + 2) * 0xff) ^ b); + } + function rle(v, d) { + pushByte(0x00); + pushByte(d - 1 + v * 0x80); } - if (c === 0xff) { + for (; i < data.length; i += 2) { + c = parseByte(data, i); + if (!c) { + if (y) rle(1, y), (y = 0); + if (++z === 0x80) rle(0, 0x80), (z = 0); + continue; + } + if (c === 0xff) { + if (z) rle(0, z), (z = 0); + if (++y === 0x20) rle(1, 0x20), (y = 0); + continue; + } + if (y) rle(1, y), (y = 0); if (z) rle(0, z), (z = 0); - if (++y === 0x20) rle(1, 0x20), (y = 0); - continue; + pushByte(c); } if (y) rle(1, y), (y = 0); if (z) rle(0, z), (z = 0); - pushByte(c); + return o; } - if (y) rle(1, y), (y = 0); - if (z) rle(0, z), (z = 0); - return o; -} -(async () => { + console.log('SRC'); const [ _, __, diff --git a/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.min.js b/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.min.js index 5bc01abc6..988ca4ac3 100644 --- a/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.min.js +++ b/packages/hardhat/tasks/CLFScripts/dist/infra/SRC.min.js @@ -1 +1 @@ -function hexString(data){if(typeof data==='string' || data instanceof String){if((data=data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/))){if(data[2].length % 2){throw new Error('Hex string length must be a multiple of 2.');}return data[2];}}throw new Error('Data must be a hex string.');}function byteToString(b){return(b | 0x100).toString(16).slice(1);}function parseByte(data,i){return parseInt(data.substr(i,2),16);}function cdCompress(data){data=hexString(data);var o='0x',z=0,y=0,i=0,c;function pushByte(b){o+=byteToString(((o.length<4*2+2)*0xff)^ b);}function rle(v,d){pushByte(0x00);pushByte(d-1+v*0x80);}for(;i{const [ _,__,___,dstContractAddress,ccipMessageId,sender,recipient,amount,srcChainSelector,dstChainSelector,token,blockNumber,dstSwapData,]=bytesArgs;const chainSelectors={[`0x${BigInt('14767482510784806043').toString(16)}`]:{urls:[`https://avalanche-fuji.infura.io/v3/${secrets.INFURA_API_KEY}`],chainId:'0xa869',nativeCurrency:'avax',priceFeed:{linkUsd:'',usdcUsd:'',nativeUsd:'',linkNative:'',maticUsd:'',ethUsd:'',},},[`0x${BigInt('16015286601757825753').toString(16)}`]:{urls:[ `https://sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://ethereum-sepolia-rpc.publicnode.com','https://ethereum-sepolia.blockpi.network/v1/rpc/public',],chainId:'0xaa36a7',nativeCurrency:'eth',priceFeed:{linkUsd:'',usdcUsd:'',nativeUsd:'',linkNative:'',},},[`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',nativeCurrency:'eth',priceFeed:{linkUsd:'0x0FB99723Aee6f420beAD13e6bBB79b7E6F034298',usdcUsd:'0x0153002d20B96532C639313c2d54c3dA09109309',nativeUsd:'0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165',linkNative:'0x3ec8593F930EA45ea58c968260e6e9FF53FC934f',},},[`0x${BigInt('10344971235874465080').toString(16)}`]:{urls:[ `https://base-sepolia.g.alchemy.com/v2/${secrets.ALCHEMY_API_KEY}`,'https://base-sepolia.blockpi.network/v1/rpc/public','https://base-sepolia-rpc.publicnode.com',],chainId:'0x14a34',nativeCurrency:'eth',priceFeed:{linkUsd:'0xb113F5A928BCfF189C998ab20d753a47F9dE5A61',usdcUsd:'0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165',nativeUsd:'0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1',linkNative:'0x56a43EB56Da12C0dc1D972ACb089c06a5dEF8e69',maticUsd:'0x12129aAC52D6B0f0125677D4E1435633E61fD25f',avaxUsd:'0xE70f2D34Fd04046aaEC26a198A35dD8F2dF5cd92',},},[`0x${BigInt('5224473277236331295').toString(16)}`]:{urls:[ `https://optimism-sepolia.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://optimism-sepolia.blockpi.network/v1/rpc/public','https://optimism-sepolia-rpc.publicnode.com',],chainId:'0xaa37dc',nativeCurrency:'eth',priceFeed:{linkUsd:'0x53f91dA33120F44893CB896b12a83551DEDb31c6',usdcUsd:'0x6e44e50E3cc14DD16e01C590DC1d7020cb36eD4C',nativeUsd:'0x61Ec26aA57019C486B10502285c5A3D4A4750AD7',linkNative:'0x98EeB02BC20c5e7079983e8F0D0D839dFc8F74fA',},},[`0x${BigInt('16281711391670634445').toString(16)}`]:{urls:[ `https://polygon-amoy.infura.io/v3/${secrets.INFURA_API_KEY}`,'https://polygon-amoy.blockpi.network/v1/rpc/public','https://polygon-amoy-bor-rpc.publicnode.com',],chainId:'0x13882',nativeCurrency:'matic',priceFeed:{linkUsd:'0xc2e2848e28B9fE430Ab44F55a8437a33802a219C',usdcUsd:'0x1b8739bB4CdF0089d07097A9Ae5Bd274b29C6F16',nativeUsd:'0x001382149eBa3441043c1c66972b4772963f5D43',linkNative:'0x408D97c89c141e60872C0835e18Dd1E670CD8781',ethUsd:'0xF0d50568e3A7e8259E16663972b11910F89BD8e7',},},[`0x${BigInt('15971525489660198786').toString(16)}`]:{urls:['https://base-rpc.publicnode.com','https://rpc.ankr.com/base'],chainId:'0x2105',nativeCurrency:'eth',priceFeed:{linkUsd:'0x17CAb8FE31E32f08326e5E27412894e49B0f9D65',usdcUsd:'0x7e860098F58bBFC8648a4311b374B1D669a2bc6B',nativeUsd:'0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70',linkNative:'0xc5E65227fe3385B88468F9A01600017cDC9F3A12',maticUsd:'0x12129aAC52D6B0f0125677D4E1435633E61fD25f',avaxUsd:'0xE70f2D34Fd04046aaEC26a198A35dD8F2dF5cd92',},},[`0x${BigInt('4949039107694359620').toString(16)}`]:{urls:['https://arbitrum-rpc.publicnode.com','https://rpc.ankr.com/arbitrum'],chainId:'0xa4b1',nativeCurrency:'eth',priceFeed:{linkUsd:'0x86E53CF1B870786351Da77A57575e79CB55812CB',usdcUsd:'0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3',nativeUsd:'0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612',linkNative:'0xb7c8Fb1dB45007F98A68Da0588e1AA524C317f27',},},[`0x${BigInt('4051577828743386545').toString(16)}`]:{urls:['https://polygon-bor-rpc.publicnode.com','https://rpc.ankr.com/polygon'],chainId:'0x89',nativeCurrency:'matic',priceFeed:{linkUsd:'0xd9FFdb71EbE7496cC440152d43986Aae0AB76665',usdcUsd:'0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7',nativeUsd:'0xAB594600376Ec9fD91F8e885dADF0CE036862dE0',linkNative:'0x5787BefDc0ECd210Dfa948264631CD53E68F7802',ethUsd:'0xF9680D99D6C9589e2a93a78A04A279e509205945',avaxUsd:'0xe01eA2fbd8D76ee323FbEd03eB9a8625EC981A10',},},[`0x${BigInt('6433500567565415381').toString(16)}`]:{urls:['https://avalanche-c-chain-rpc.publicnode.com','https://rpc.ankr.com/avalanche'],chainId:'0xa86a',nativeCurrency:'avax',priceFeed:{linkUsd:'0x49ccd9ca821EfEab2b98c60dC60F518E765EDe9a',usdcUsd:'0xF096872672F44d6EBA71458D74fe67F9a77a23B9',nativeUsd:'0x0A77230d17318075983913bC2145DB16C7366156',linkNative:'0x1b8a25F73c9420dD507406C3A3816A276b62f56a',ethUsd:'0x976B3D034E162d8bD72D6b9C989d545b839003b0',maticUsd:'0x1db18D41E4AD2403d9f52b5624031a2D9932Fd73',},},};const UINT256_BYTES_LENGTH=32;const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));const getPercent=(value,percent)=>(BigInt(value)*BigInt(percent))/100n;const getPriceRates=async(provider,chainSelector)=>{const priceFeedsAbi=['function latestRoundData()external view returns(uint80,int256,uint256,uint256,uint80)'];const linkUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.linkUsd,priceFeedsAbi,provider);const usdcUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.usdcUsd,priceFeedsAbi,provider);const nativeUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.nativeUsd,priceFeedsAbi,provider,);const linkNativeContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.linkNative,priceFeedsAbi,provider,);const promises=[ linkUsdContract.latestRoundData(),usdcUsdContract.latestRoundData(),nativeUsdContract.latestRoundData(),linkNativeContract.latestRoundData(),];const promiseUndefined=async()=>{return new Promise(resolve=>{resolve(undefined);});};if(chainSelectors[chainSelector].priceFeed.maticUsd){const maticUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.maticUsd,priceFeedsAbi,provider,);promises.push(maticUsdContract.latestRoundData());}else{promises.push(promiseUndefined());}if(chainSelectors[chainSelector].priceFeed.ethUsd){const ethUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.ethUsd,priceFeedsAbi,provider);promises.push(ethUsdContract.latestRoundData());}else{promises.push(promiseUndefined());}if(chainSelectors[chainSelector].priceFeed.avaxUsd){const avaxUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.avaxUsd,priceFeedsAbi,provider,);promises.push(avaxUsdContract.latestRoundData());}else{promises.push(promiseUndefined());}const [linkUsd,usdcUsd,nativeUsd,linkNative,maticUsd,ethUsd,avaxUsd]=await Promise.all(promises);return{linkUsdc:linkUsd[1]>0n ?(linkUsd[1]*10n**18n)/usdcUsd[1]:0n,nativeUsdc:nativeUsd[1]>0n ?(nativeUsd[1]*10n**18n)/usdcUsd[1]:0n,linkNative:linkNative[1]>0 ? linkNative[1]:0n,nativeUsd:nativeUsd[1]>0 ? nativeUsd[1]:0n,maticUsd:maticUsd ? maticUsd[1]:undefined,ethUsd:ethUsd ? ethUsd[1]:undefined,avaxUsd:avaxUsd ? avaxUsd[1]:undefined,};};const constructResult=items=>{const encodedValues=items.map(value=>Functions.encodeUint256(BigInt(value)));const totalLength=encodedValues.length*UINT256_BYTES_LENGTH;const result=new Uint8Array(totalLength);let offset=0;for(const encoded of encodedValues){result.set(encoded,offset);offset+=UINT256_BYTES_LENGTH;}return result;};const getDstGasPriceInSrcCurrency=(_gasPrice,srcPriceFeeds)=>{const getGasPriceByPriceFeeds=(nativeUsdPriceFeed,dstAssetUsdPriceFeed,gasPriceInDstCurrency)=>{if(dstAssetUsdPriceFeed===undefined)return 1n;const srcNativeDstNativeRate=nativeUsdPriceFeed/dstAssetUsdPriceFeed;const dstGasPriceInSrcCurrency=gasPriceInDstCurrency/srcNativeDstNativeRate;return dstGasPriceInSrcCurrency<1n ? 1n:dstGasPriceInSrcCurrency;};const srcNativeCurrency=chainSelectors[srcChainSelector].nativeCurrency;const dstNativeCurrency=chainSelectors[dstChainSelector].nativeCurrency;if(srcNativeCurrency !==dstNativeCurrency){return getGasPriceByPriceFeeds(srcPriceFeeds.nativeUsd,srcPriceFeeds[`${dstNativeCurrency}Usd`],_gasPrice);}return _gasPrice;};let nonce=0;let retries=0;let gasPrice;const compressedDstSwapData=cdCompress(dstSwapData);const sendTransaction=async(contract,signer,txOptions)=>{try{if((await contract.s_transactions(ccipMessageId))[1] !=='0x0000000000000000000000000000000000000000')return;await contract.addUnconfirmedTX(ccipMessageId,sender,recipient,amount,srcChainSelector,token,blockNumber,compressedDstSwapData,txOptions,);}catch(err){const{message,code}=err;if(retries>=5){throw new Error('retries reached the limit '+err.message?.slice(0,200));}else if(code==='NONCE_EXPIRED' || message?.includes('replacement fee too low')){await sleep(1000+Math.random()*1500);retries++;await sendTransaction(contract,signer,{...txOptions,nonce:nonce++,});}else if(code==='UNKNOWN_ERROR' && message?.includes('already known')){return;}else{throw new Error(err.message?.slice(0,255));}}};try{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=chainSelectors[srcChainSelector].urls.includes(this.url)? chainSelectors[srcChainSelector].chainId:chainSelectors[dstChainSelector].chainId;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 dstUrl=chainSelectors[dstChainSelector].urls[Math.floor(Math.random()*chainSelectors[dstChainSelector].urls.length)];const provider=new FunctionsJsonRpcProvider(dstUrl);const wallet=new ethers.Wallet('0x'+secrets.MESSENGER_0_PRIVATE_KEY,provider);const signer=wallet.connect(provider);const abi=[ 'function addUnconfirmedTX(bytes32,address,address,uint256,uint64,uint8,uint256,bytes)external','function s_transactions(bytes32)view returns(bytes32,address,address,uint256,uint8,uint64,bool,bytes)',];const contract=new ethers.Contract(dstContractAddress,abi,signer);const [feeData,nonce]=await Promise.all([provider.getFeeData(),provider.getTransactionCount(wallet.address)]);gasPrice=feeData.gasPrice;await sendTransaction(contract,signer,{nonce,maxFeePerGas:dstChainSelector===[`0x${BigInt('4051577828743386545').toString(16)}`] ? gasPrice:gasPrice+getPercent(gasPrice,10),});const srcUrl=chainSelectors[srcChainSelector].urls[Math.floor(Math.random()*chainSelectors[srcChainSelector].urls.length)];const srcChainProvider=new FunctionsJsonRpcProvider(srcUrl);const [srcFeeData,srcPriceFeeds]=await Promise.all([ srcChainProvider.getFeeData(),getPriceRates(srcChainProvider,srcChainSelector),]);const dstGasPriceInSrcCurrency=getDstGasPriceInSrcCurrency(gasPrice,srcPriceFeeds);return constructResult([ dstGasPriceInSrcCurrency,srcFeeData.gasPrice,dstChainSelector,srcPriceFeeds.linkUsdc,srcPriceFeeds.nativeUsdc,srcPriceFeeds.linkNative,]);}catch(error){const{message}=error;if(message?.includes('Exceeded maximum of 20 HTTP queries')){return new Uint8Array(1);}else{throw new Error(message?.slice(0,255));}}})(); \ No newline at end of file +(async()=>{function hexString(data){if(typeof data==='string' || data instanceof String){if((data=data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/))){if(data[2].length % 2){throw new Error('Hex string length must be a multiple of 2.');}return data[2];}}throw new Error('Data must be a hex string.');}function byteToString(b){return(b | 0x100).toString(16).slice(1);}function parseByte(data,i){return parseInt(data.substr(i,2),16);}function cdCompress(data){data=hexString(data);var o='0x',z=0,y=0,i=0,c;function pushByte(b){o+=byteToString(((o.length<4*2+2)*0xff)^ b);}function rle(v,d){pushByte(0x00);pushByte(d-1+v*0x80);}for(;inew Promise(resolve=>setTimeout(resolve,ms));const getPercent=(value,percent)=>(BigInt(value)*BigInt(percent))/100n;const getPriceRates=async(provider,chainSelector)=>{const priceFeedsAbi=['function latestRoundData()external view returns(uint80,int256,uint256,uint256,uint80)'];const linkUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.linkUsd,priceFeedsAbi,provider);const usdcUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.usdcUsd,priceFeedsAbi,provider);const nativeUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.nativeUsd,priceFeedsAbi,provider,);const linkNativeContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.linkNative,priceFeedsAbi,provider,);const promises=[ linkUsdContract.latestRoundData(),usdcUsdContract.latestRoundData(),nativeUsdContract.latestRoundData(),linkNativeContract.latestRoundData(),];const promiseUndefined=async()=>{return new Promise(resolve=>{resolve(undefined);});};if(chainSelectors[chainSelector].priceFeed.maticUsd){const maticUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.maticUsd,priceFeedsAbi,provider,);promises.push(maticUsdContract.latestRoundData());}else{promises.push(promiseUndefined());}if(chainSelectors[chainSelector].priceFeed.ethUsd){const ethUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.ethUsd,priceFeedsAbi,provider);promises.push(ethUsdContract.latestRoundData());}else{promises.push(promiseUndefined());}if(chainSelectors[chainSelector].priceFeed.avaxUsd){const avaxUsdContract=new ethers.Contract(chainSelectors[chainSelector].priceFeed.avaxUsd,priceFeedsAbi,provider,);promises.push(avaxUsdContract.latestRoundData());}else{promises.push(promiseUndefined());}const [linkUsd,usdcUsd,nativeUsd,linkNative,maticUsd,ethUsd,avaxUsd]=await Promise.all(promises);return{linkUsdc:linkUsd[1]>0n ?(linkUsd[1]*10n**18n)/usdcUsd[1]:0n,nativeUsdc:nativeUsd[1]>0n ?(nativeUsd[1]*10n**18n)/usdcUsd[1]:0n,linkNative:linkNative[1]>0 ? linkNative[1]:0n,nativeUsd:nativeUsd[1]>0 ? nativeUsd[1]:0n,maticUsd:maticUsd ? maticUsd[1]:undefined,ethUsd:ethUsd ? ethUsd[1]:undefined,avaxUsd:avaxUsd ? avaxUsd[1]:undefined,};};const constructResult=items=>{const encodedValues=items.map(value=>Functions.encodeUint256(BigInt(value)));const totalLength=encodedValues.length*UINT256_BYTES_LENGTH;const result=new Uint8Array(totalLength);let offset=0;for(const encoded of encodedValues){result.set(encoded,offset);offset+=UINT256_BYTES_LENGTH;}return result;};const getDstGasPriceInSrcCurrency=(_gasPrice,srcPriceFeeds)=>{const getGasPriceByPriceFeeds=(nativeUsdPriceFeed,dstAssetUsdPriceFeed,gasPriceInDstCurrency)=>{if(dstAssetUsdPriceFeed===undefined)return 1n;const srcNativeDstNativeRate=nativeUsdPriceFeed/dstAssetUsdPriceFeed;const dstGasPriceInSrcCurrency=gasPriceInDstCurrency/srcNativeDstNativeRate;return dstGasPriceInSrcCurrency<1n ? 1n:dstGasPriceInSrcCurrency;};const srcNativeCurrency=chainSelectors[srcChainSelector].nativeCurrency;const dstNativeCurrency=chainSelectors[dstChainSelector].nativeCurrency;if(srcNativeCurrency !==dstNativeCurrency){return getGasPriceByPriceFeeds(srcPriceFeeds.nativeUsd,srcPriceFeeds[`${dstNativeCurrency}Usd`],_gasPrice);}return _gasPrice;};let nonce=0;let retries=0;let gasPrice;const compressedDstSwapData=cdCompress(dstSwapData);const sendTransaction=async(contract,signer,txOptions)=>{try{if((await contract.s_transactions(ccipMessageId))[1] !=='0x0000000000000000000000000000000000000000')return;await contract.addUnconfirmedTX(ccipMessageId,sender,recipient,amount,srcChainSelector,token,blockNumber,compressedDstSwapData,txOptions,);}catch(err){const{message,code}=err;if(retries>=5){throw new Error('retries reached the limit '+err.message?.slice(0,200));}else if(code==='NONCE_EXPIRED' || message?.includes('replacement fee too low')){await sleep(1000+Math.random()*1500);retries++;await sendTransaction(contract,signer,{...txOptions,nonce:nonce++,});}else if(code==='UNKNOWN_ERROR' && message?.includes('already known')){return;}else{throw new Error(err.message?.slice(0,255));}}};try{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=chainSelectors[srcChainSelector].urls.includes(this.url)? chainSelectors[srcChainSelector].chainId:chainSelectors[dstChainSelector].chainId;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 dstUrl=chainSelectors[dstChainSelector].urls[Math.floor(Math.random()*chainSelectors[dstChainSelector].urls.length)];const provider=new FunctionsJsonRpcProvider(dstUrl);const wallet=new ethers.Wallet('0x'+secrets.MESSENGER_0_PRIVATE_KEY,provider);const signer=wallet.connect(provider);const abi=[ 'function addUnconfirmedTX(bytes32,address,address,uint256,uint64,uint8,uint256,bytes)external','function s_transactions(bytes32)view returns(bytes32,address,address,uint256,uint8,uint64,bool,bytes)',];const contract=new ethers.Contract(dstContractAddress,abi,signer);const [feeData,nonce]=await Promise.all([provider.getFeeData(),provider.getTransactionCount(wallet.address)]);gasPrice=feeData.gasPrice;await sendTransaction(contract,signer,{nonce,maxFeePerGas:dstChainSelector===[`0x${BigInt('4051577828743386545').toString(16)}`] ? gasPrice:gasPrice+getPercent(gasPrice,10),});const srcUrl=chainSelectors[srcChainSelector].urls[Math.floor(Math.random()*chainSelectors[srcChainSelector].urls.length)];const srcChainProvider=new FunctionsJsonRpcProvider(srcUrl);const [srcFeeData,srcPriceFeeds]=await Promise.all([ srcChainProvider.getFeeData(),getPriceRates(srcChainProvider,srcChainSelector),]);const dstGasPriceInSrcCurrency=getDstGasPriceInSrcCurrency(gasPrice,srcPriceFeeds);return constructResult([ dstGasPriceInSrcCurrency,srcFeeData.gasPrice,dstChainSelector,srcPriceFeeds.linkUsdc,srcPriceFeeds.nativeUsdc,srcPriceFeeds.linkNative,]);}catch(error){const{message}=error;if(message?.includes('Exceeded maximum of 20 HTTP queries')){return new Uint8Array(1);}else{throw new Error(message?.slice(0,255));}}})(); \ No newline at end of file diff --git a/packages/hardhat/tasks/CLFScripts/simulate.ts b/packages/hardhat/tasks/CLFScripts/simulate.ts index 54a80943d..2a8e283fe 100644 --- a/packages/hardhat/tasks/CLFScripts/simulate.ts +++ b/packages/hardhat/tasks/CLFScripts/simulate.ts @@ -7,13 +7,15 @@ import getSimulationArgs from './simulationArgs'; import {simulateScript} from '@chainlink/functions-toolkit'; import {log} from '../../utils'; import buildScript from './build'; +import {decodeCLFResponse} from './decodeCLFResponse'; /** * Simulates the execution of a script with the given arguments. * @param scriptPath - The path to the script file to simulate. + * @param scriptName - The name of the script to simulate. * @param args - The array of arguments to pass to the simulation. */ -async function simulateCLFScript(scriptPath: string, args: string[]): Promise { +async function simulateCLFScript(scriptPath: string, scriptName: string, args: string[]): Promise { if (!fs.existsSync(scriptPath)) { console.error(`File not found: ${scriptPath}`); return; @@ -22,7 +24,7 @@ async function simulateCLFScript(scriptPath: string, args: string[]): Promise simulateCLFScript(scriptPath, bytesArgs)); + const promises = Array.from({length: concurrency}, () => simulateCLFScript(scriptPath, scriptName, bytesArgs)); await Promise.all(promises); }); diff --git a/packages/hardhat/tasks/CLFScripts/src/infra/SRC.js b/packages/hardhat/tasks/CLFScripts/src/infra/SRC.js index 918138f93..aa5d861de 100644 --- a/packages/hardhat/tasks/CLFScripts/src/infra/SRC.js +++ b/packages/hardhat/tasks/CLFScripts/src/infra/SRC.js @@ -5,67 +5,68 @@ numAllowedQueries: 2 – a minimum to initialise Viem. // todo: convert var names to single characters /*BUILD_REMOVES_EVERYTHING_ABOVE_THIS_LINE*/ -/* SOLADY BEGIN */ -function hexString(data) { - if (typeof data === 'string' || data instanceof String) { - if ((data = data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/))) { - if (data[2].length % 2) { - throw new Error('Hex string length must be a multiple of 2.'); +(async () => { + /* SOLADY BEGIN */ + function hexString(data) { + if (typeof data === 'string' || data instanceof String) { + if ((data = data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/))) { + if (data[2].length % 2) { + throw new Error('Hex string length must be a multiple of 2.'); + } + return data[2]; } - return data[2]; } + throw new Error('Data must be a hex string.'); } - throw new Error('Data must be a hex string.'); -} -function byteToString(b) { - return (b | 0x100).toString(16).slice(1); -} + function byteToString(b) { + return (b | 0x100).toString(16).slice(1); + } -function parseByte(data, i) { - return parseInt(data.substr(i, 2), 16); -} + function parseByte(data, i) { + return parseInt(data.substr(i, 2), 16); + } -function cdCompress(data) { - data = hexString(data); - var o = '0x', - z = 0, - y = 0, - i = 0, - c; + function cdCompress(data) { + data = hexString(data); + var o = '0x', + z = 0, + y = 0, + i = 0, + c; - function pushByte(b) { - o += byteToString(((o.length < 4 * 2 + 2) * 0xff) ^ b); - } + function pushByte(b) { + o += byteToString(((o.length < 4 * 2 + 2) * 0xff) ^ b); + } - function rle(v, d) { - pushByte(0x00); - pushByte(d - 1 + v * 0x80); - } + function rle(v, d) { + pushByte(0x00); + pushByte(d - 1 + v * 0x80); + } - for (; i < data.length; i += 2) { - c = parseByte(data, i); - if (!c) { + for (; i < data.length; i += 2) { + c = parseByte(data, i); + if (!c) { + if (y) rle(1, y), (y = 0); + if (++z === 0x80) rle(0, 0x80), (z = 0); + continue; + } + if (c === 0xff) { + if (z) rle(0, z), (z = 0); + if (++y === 0x20) rle(1, 0x20), (y = 0); + continue; + } if (y) rle(1, y), (y = 0); - if (++z === 0x80) rle(0, 0x80), (z = 0); - continue; - } - if (c === 0xff) { if (z) rle(0, z), (z = 0); - if (++y === 0x20) rle(1, 0x20), (y = 0); - continue; + pushByte(c); } if (y) rle(1, y), (y = 0); if (z) rle(0, z), (z = 0); - pushByte(c); + return o; } - if (y) rle(1, y), (y = 0); - if (z) rle(0, z), (z = 0); - return o; -} -/* SOLADY END */ + /* SOLADY END */ -(async () => { + console.log('SRC'); const [ _, __, From 7a09b1e2c9d2fffd99a3e4def722ca2e483f3196 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 13 Nov 2024 16:11:23 +0000 Subject: [PATCH 2/3] fixparentPoolCLFCLA --- packages/hardhat/.husky/pre-commit | 1 + packages/hardhat/contracts/ParentPoolCLFCLA.sol | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 packages/hardhat/.husky/pre-commit diff --git a/packages/hardhat/.husky/pre-commit b/packages/hardhat/.husky/pre-commit new file mode 100644 index 000000000..72c4429bc --- /dev/null +++ b/packages/hardhat/.husky/pre-commit @@ -0,0 +1 @@ +npm test diff --git a/packages/hardhat/contracts/ParentPoolCLFCLA.sol b/packages/hardhat/contracts/ParentPoolCLFCLA.sol index 31f02aa7c..66d781e40 100644 --- a/packages/hardhat/contracts/ParentPoolCLFCLA.sol +++ b/packages/hardhat/contracts/ParentPoolCLFCLA.sol @@ -250,7 +250,7 @@ contract ParentPoolCLFCLA is uint256 childPoolsLiquidity, bytes1[] memory depositsOnTheWayIdsToDelete ) = _decodeCLFResponse(response); -5 + request.childPoolsLiquiditySnapshot = childPoolsLiquidity; _deleteDepositsOnTheWayByIndexes(depositsOnTheWayIdsToDelete); From 027d0eca91e54ee05c741217e4cfbc3ca5650aa3 Mon Sep 17 00:00:00 2001 From: Oleg Date: Thu, 14 Nov 2024 12:30:18 +0000 Subject: [PATCH 3/3] naming --- .../contracts/Interfaces/IParentPool.sol | 13 +- .../contracts/Libraries/ParentPoolStorage.sol | 2 +- packages/hardhat/contracts/ParentPool.sol | 12 +- .../hardhat/contracts/ParentPoolCLFCLA.sol | 10 +- .../CLFScripts/dist/pool/parentPoolEval.js | 2 +- .../dist/pool/parentPoolEval.min.js | 2 +- packages/hardhat/tasks/CLFScripts/simulate.ts | 10 +- .../CLFScripts/src/pool/collectLiquidity.js | 119 ---------- .../src/pool/distributeLiquidity.js | 168 -------------- .../CLFScripts/src/pool/getTotalBalance.js | 214 ------------------ .../CLFScripts/src/pool/parentPoolEval.js | 2 +- 11 files changed, 24 insertions(+), 530 deletions(-) delete mode 100644 packages/hardhat/tasks/CLFScripts/src/pool/collectLiquidity.js delete mode 100644 packages/hardhat/tasks/CLFScripts/src/pool/distributeLiquidity.js delete mode 100644 packages/hardhat/tasks/CLFScripts/src/pool/getTotalBalance.js diff --git a/packages/hardhat/contracts/Interfaces/IParentPool.sol b/packages/hardhat/contracts/Interfaces/IParentPool.sol index df32b7bc4..9cda2ead6 100644 --- a/packages/hardhat/contracts/Interfaces/IParentPool.sol +++ b/packages/hardhat/contracts/Interfaces/IParentPool.sol @@ -9,12 +9,6 @@ import {ICCIP} from "./ICCIP.sol"; interface IParentPool is IPool { /* TYPE DECLARATIONS */ - enum FunctionsRequestType { - getTotalPoolsBalance, - liquidityRedistribution, - withdrawalLiquidityCollection - } - enum RedistributeLiquidityType { addPool, removePool @@ -28,9 +22,10 @@ interface IParentPool is IPool { ///@notice Struct to track Functions Requests Type enum CLFRequestType { - startDeposit_getChildPoolsLiquidity, //Deposits - startWithdrawal_getChildPoolsLiquidity, //Start Withdrawals - performUpkeep_requestLiquidityTransfer + startDeposit_getChildPoolsLiquidity, + startWithdrawal_getChildPoolsLiquidity, + withdrawal_requestLiquidityCollection, + liquidityRedistribution } struct WithdrawRequest { diff --git a/packages/hardhat/contracts/Libraries/ParentPoolStorage.sol b/packages/hardhat/contracts/Libraries/ParentPoolStorage.sol index e7417c7f0..1204cb6a0 100644 --- a/packages/hardhat/contracts/Libraries/ParentPoolStorage.sol +++ b/packages/hardhat/contracts/Libraries/ParentPoolStorage.sol @@ -15,7 +15,7 @@ contract ParentPoolStorage { ///@notice variable to store the Chainlink Function DON Secret Version uint64 internal s_donHostedSecretsVersion; ///@notice variable to store the Chainlink Function Source Hashsum - bytes32 internal s_getBalanceJsCodeHashSum; + bytes32 internal s_getChildPoolsLiquidityJsCodeHashSum; ///@notice variable to store Ethers Hashsum bytes32 internal s_ethersHashSum; ///@notice variable to store not processed amounts deposited by LPs diff --git a/packages/hardhat/contracts/ParentPool.sol b/packages/hardhat/contracts/ParentPool.sol index 4b0520e86..06dd820a4 100644 --- a/packages/hardhat/contracts/ParentPool.sol +++ b/packages/hardhat/contracts/ParentPool.sol @@ -278,9 +278,9 @@ contract ParentPool is IParentPool, CCIPReceiver, ParentPoolCommon, ParentPoolSt } bytes[] memory args = new bytes[](3); - args[0] = abi.encodePacked(s_getBalanceJsCodeHashSum); + args[0] = abi.encodePacked(s_getChildPoolsLiquidityJsCodeHashSum); args[1] = abi.encodePacked(s_ethersHashSum); - args[2] = abi.encodePacked(FunctionsRequestType.getTotalPoolsBalance); + args[2] = abi.encodePacked(CLFRequestType.startDeposit_getChildPoolsLiquidity); bytes memory delegateCallArgs = abi.encodeWithSelector( IParentPoolCLFCLA.sendCLFRequest.selector, @@ -350,7 +350,7 @@ contract ParentPool is IParentPool, CCIPReceiver, ParentPoolCommon, ParentPoolSt } bytes[] memory args = new bytes[](2); - args[0] = abi.encodePacked(s_getBalanceJsCodeHashSum); + args[0] = abi.encodePacked(s_getChildPoolsLiquidityJsCodeHashSum); args[1] = abi.encodePacked(s_ethersHashSum); bytes32 withdrawalId = keccak256( @@ -536,7 +536,7 @@ contract ParentPool is IParentPool, CCIPReceiver, ParentPoolCommon, ParentPoolSt function setGetBalanceJsCodeHashSum( bytes32 _hashSum ) external payable onlyProxyContext onlyOwner { - s_getBalanceJsCodeHashSum = _hashSum; + s_getChildPoolsLiquidityJsCodeHashSum = _hashSum; } /** @@ -574,7 +574,7 @@ contract ParentPool is IParentPool, CCIPReceiver, ParentPoolCommon, ParentPoolSt bytes[] memory args = new bytes[](6); args[0] = abi.encodePacked(s_distributeLiquidityJsCodeHashSum); args[1] = abi.encodePacked(s_ethersHashSum); - args[2] = abi.encodePacked(FunctionsRequestType.liquidityRedistribution); + args[2] = abi.encodePacked(CLFRequestType.liquidityRedistribution); args[3] = abi.encodePacked(_chainSelector); args[4] = abi.encodePacked(distributeLiquidityRequestId); args[5] = abi.encodePacked(RedistributeLiquidityType.addPool); @@ -619,7 +619,7 @@ contract ParentPool is IParentPool, CCIPReceiver, ParentPoolCommon, ParentPoolSt bytes[] memory args = new bytes[](6); args[0] = abi.encodePacked(s_distributeLiquidityJsCodeHashSum); args[1] = abi.encodePacked(s_ethersHashSum); - args[2] = abi.encodePacked(FunctionsRequestType.liquidityRedistribution); + args[2] = abi.encodePacked(CLFRequestType.liquidityRedistribution); args[3] = abi.encodePacked(_chainSelector); args[4] = abi.encodePacked(distributeLiquidityRequestId); args[5] = abi.encodePacked(RedistributeLiquidityType.removePool); diff --git a/packages/hardhat/contracts/ParentPoolCLFCLA.sol b/packages/hardhat/contracts/ParentPoolCLFCLA.sol index 66d781e40..72068f464 100644 --- a/packages/hardhat/contracts/ParentPoolCLFCLA.sol +++ b/packages/hardhat/contracts/ParentPoolCLFCLA.sol @@ -108,7 +108,7 @@ contract ParentPoolCLFCLA is _handleStartWithdrawalCLFFulfill(requestId, response); delete s_withdrawalIdByCLFRequestId[requestId]; } else if ( - requestType == IParentPool.CLFRequestType.performUpkeep_requestLiquidityTransfer + requestType == IParentPool.CLFRequestType.withdrawal_requestLiquidityCollection ) { _handleAutomationCLFFulfill(requestId); } @@ -189,9 +189,7 @@ contract ParentPoolCLFCLA is liquidityRequestedFromEachPool ); - s_clfRequestTypes[reqId] = IParentPool - .CLFRequestType - .performUpkeep_requestLiquidityTransfer; + s_clfRequestTypes[reqId] = IParentPool.CLFRequestType.withdrawal_requestLiquidityCollection; _addWithdrawalOnTheWayAmountById(withdrawalId); emit WithdrawUpkeepPerformed(reqId); @@ -426,7 +424,9 @@ contract ParentPoolCLFCLA is bytes[] memory args = new bytes[](5); args[0] = abi.encodePacked(s_collectLiquidityJsCodeHashSum); args[1] = abi.encodePacked(s_ethersHashSum); - args[2] = abi.encodePacked(IParentPool.FunctionsRequestType.withdrawalLiquidityCollection); + args[2] = abi.encodePacked( + IParentPool.CLFRequestType.withdrawal_requestLiquidityCollection + ); args[3] = abi.encodePacked(liquidityRequestedFromEachPool); args[4] = abi.encodePacked(withdrawalId); diff --git a/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.js b/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.js index ca5adcfab..5686e7815 100644 --- a/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.js +++ b/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.js @@ -4,7 +4,7 @@ try { const q = 'https://raw.githubusercontent.com/concero/contracts-ccip/' + 'master' + - `/packages/hardhat/tasks/CLFScripts/dist/pool/${f === '0x02' ? 'collectLiquidity' : f === '0x01' ? 'distributeLiquidity' : 'getTotalBalance'}.min.js`; + `/packages/hardhat/tasks/CLFScripts/dist/pool/${f === '0x02' ? 'collectLiquidity' : f === '0x01' ? 'distributeLiquidity' : 'getChildPoolsLiquidity'}.min.js`; const [t, p] = await Promise.all([fetch(u), fetch(q)]); const [e, c] = await Promise.all([t.text(), p.text()]); const g = async s => { diff --git a/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.min.js b/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.min.js index 34f04ecea..069b282fe 100644 --- a/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.min.js +++ b/packages/hardhat/tasks/CLFScripts/dist/pool/parentPoolEval.min.js @@ -1 +1 @@ -try{const [b,o,f]=bytesArgs;const u='https://raw.githubusercontent.com/ethers-io/ethers.js/v6.10.0/dist/ethers.umd.min.js';const q='https://raw.githubusercontent.com/concero/contracts-ccip/'+'master'+`/packages/hardhat/tasks/CLFScripts/dist/pool/${f==='0x02' ? 'collectLiquidity':f==='0x01' ? 'distributeLiquidity':'getTotalBalance'}.min.js`;const [t,p]=await Promise.all([fetch(u),fetch(q)]);const [e,c]=await Promise.all([t.text(),p.text()]);const g=async s=>{return('0x'+Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(s)))).map(v=>('0'+v.toString(16)).slice(-2).toLowerCase()).join(''));};const r=await g(c);const x=await g(e);if(r===b.toLowerCase()&& x===o.toLowerCase()){const ethers=new Function(e+';return ethers;')();return await eval(c);}throw new Error(`${r}!=${b}||${x}!=${o}`);}catch(e){throw new Error(e.message.slice(0,255));} \ No newline at end of file +try{const [b,o,f]=bytesArgs;const u='https://raw.githubusercontent.com/ethers-io/ethers.js/v6.10.0/dist/ethers.umd.min.js';const q='https://raw.githubusercontent.com/concero/contracts-ccip/'+'master'+`/packages/hardhat/tasks/CLFScripts/dist/pool/${f==='0x02' ? 'collectLiquidity':f==='0x01' ? 'distributeLiquidity':'getChildPoolsLiquidity'}.min.js`;const [t,p]=await Promise.all([fetch(u),fetch(q)]);const [e,c]=await Promise.all([t.text(),p.text()]);const g=async s=>{return('0x'+Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(s)))).map(v=>('0'+v.toString(16)).slice(-2).toLowerCase()).join(''));};const r=await g(c);const x=await g(e);if(r===b.toLowerCase()&& x===o.toLowerCase()){const ethers=new Function(e+';return ethers;')();return await eval(c);}throw new Error(`${r}!=${b}||${x}!=${o}`);}catch(e){throw new Error(e.message.slice(0,255));} \ No newline at end of file diff --git a/packages/hardhat/tasks/CLFScripts/simulate.ts b/packages/hardhat/tasks/CLFScripts/simulate.ts index 2a8e283fe..19c0d88c8 100644 --- a/packages/hardhat/tasks/CLFScripts/simulate.ts +++ b/packages/hardhat/tasks/CLFScripts/simulate.ts @@ -69,14 +69,14 @@ task('clf-script-simulate', 'Executes the JavaScript source code locally') case 'infra_dst': scriptPath = path.join(basePath, './infra/DST.min.js'); break; - case 'pool_get_total_balance': - scriptPath = path.join(basePath, './pool/getTotalBalance.min.js'); + case 'pool_get_child_pools_liquidity': + scriptPath = path.join(basePath, './pool/getChildPoolsLiquidity.min.js'); break; - case 'collect_liq': - scriptPath = path.join(basePath, './pool/collectLiquidity.min.js'); + case 'pool_collect_liq': + scriptPath = path.join(basePath, './pool/withdrawalLiquidityCollection.min.js'); break; case 'pool_distribute_liq': - scriptPath = path.join(basePath, './pool/distributeLiquidity.min.js'); + scriptPath = path.join(basePath, './pool/redistributePoolsLiquidity.min.js'); break; default: console.error(`Unknown function: ${scriptName}`); diff --git a/packages/hardhat/tasks/CLFScripts/src/pool/collectLiquidity.js b/packages/hardhat/tasks/CLFScripts/src/pool/collectLiquidity.js deleted file mode 100644 index 11a70e8c6..000000000 --- a/packages/hardhat/tasks/CLFScripts/src/pool/collectLiquidity.js +++ /dev/null @@ -1,119 +0,0 @@ -(async () => { - try { - 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_FUJI}').toString(16)}`]: { - urls: [ - `https://avalanche-fuji.infura.io/v3/${secrets.INFURA_API_KEY}`, - 'https://avalanche-fuji-c-chain-rpc.publicnode.com', - 'https://avalanche-fuji.blockpi.network/v1/rpc/public', - ], - chainId: '0xa869', - 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}', - // }, - }; - - const getChainIdByUrl = url => { - for (const chain in chainSelectors) { - if (chainSelectors[chain].urls.includes(url)) return chainSelectors[chain].chainId; - } - 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)}`; - - 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; - } -})(); diff --git a/packages/hardhat/tasks/CLFScripts/src/pool/distributeLiquidity.js b/packages/hardhat/tasks/CLFScripts/src/pool/distributeLiquidity.js deleted file mode 100644 index 5d28c43d2..000000000 --- a/packages/hardhat/tasks/CLFScripts/src/pool/distributeLiquidity.js +++ /dev/null @@ -1,168 +0,0 @@ -(async () => { - try { - const [_, __, ___, newPoolChainSelector, distributeLiquidityRequestId, distributionType] = 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_FUJI}').toString(16)}`]: { - // urls: [ - // `https://avalanche-fuji.infura.io/v3/${secrets.INFURA_API_KEY}`, - // 'https://avalanche-fuji-c-chain-rpc.publicnode.com', - // 'https://avalanche-fuji.blockpi.network/v1/rpc/public', - // ], - // chainId: '0xa869', - // usdcAddress: '${USDC_FUJI}', - // poolAddress: '${CHILD_POOL_PROXY_FUJI}', - // }, - - // mainnet - [`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_BASE}').toString(16)}`]: { - urls: [ - `https://base-mainnet.g.alchemy.com/v2/${secrets.ALCHEMY_API_KEY}`, - 'https://base.blockpi.network/v1/rpc/public', - 'https://base-rpc.publicnode.com', - ], - chainId: '0x2105', - usdcAddress: '${USDC_BASE}', - poolAddress: '${PARENT_POOL_PROXY_BASE}', - }, - }; - - const erc20Abi = ['function balanceOf(address) external view returns (uint256)']; - const poolAbi = [ - 'function s_loansInUse() external view returns (uint256)', - 'function distributeLiquidity(uint64, uint256, bytes32) external', - 'function liquidatePool(bytes32) external', - ]; - - const chainSelectorsArr = Object.keys(chainSelectors); - - 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'}]; - } - 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 getProviderByChainSelector = _chainSelector => { - const url = - chainSelectors[_chainSelector].urls[Math.floor(Math.random() * chainSelectors[_chainSelector].urls.length)]; - return new FunctionsJsonRpcProvider(url); - }; - - const getSignerByChainSelector = _chainSelector => { - const provider = getProviderByChainSelector(_chainSelector); - const wallet = new ethers.Wallet('0x' + secrets.POOL_MESSENGER_0_PRIVATE_KEY, provider); - return wallet.connect(provider); - }; - - if (distributionType === '0x0') { - const getPoolsBalances = async () => { - const getBalancePromises = []; - - for (const chain in chainSelectors) { - if (chain === newPoolChainSelector) 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); - getBalancePromises.push(erc20.balanceOf(chainSelectors[chain].poolAddress)); - getBalancePromises.push(pool.s_loansInUse()); - } - - const results = await Promise.all(getBalancePromises); - const balances = {}; - - for (let i = 0, k = 0; i < results.length; i += 2, k++) { - balances[chainSelectorsArr[k]] = results[i] + results[i + 1]; - } - - return balances; - }; - - const poolsBalances = await getPoolsBalances(); - const poolsTotalBalance = chainSelectorsArr.reduce((acc, pool) => acc + poolsBalances[pool], 0n); - const newPoolsCount = Object.keys(chainSelectors).length + 1; - const newPoolBalance = poolsTotalBalance / BigInt(newPoolsCount); - const distributeAmountPromises = []; - - for (const chain in chainSelectors) { - if (chain === newPoolChainSelector) continue; - const signer = getSignerByChainSelector(chain); - const poolContract = new ethers.Contract(chainSelectors[chain].poolAddress, poolAbi, signer); - const amountToDistribute = poolsBalances[chain] - newPoolBalance; - distributeAmountPromises.push( - poolContract.distributeLiquidity(newPoolChainSelector, amountToDistribute, distributeLiquidityRequestId), - ); - } - - await Promise.all(distributeAmountPromises); - - return Functions.encodeUint256(1n); - } else if (distributionType === '0x1') { - const signer = getSignerByChainSelector(newPoolChainSelector); - const poolContract = new ethers.Contract(chainSelectors[newPoolChainSelector].poolAddress, poolAbi, signer); - await poolContract.liquidatePool(distributeLiquidityRequestId); - - return Functions.encodeUint256(1n); - } - - throw new Error('Invalid distribution type'); - } 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; - } -})(); diff --git a/packages/hardhat/tasks/CLFScripts/src/pool/getTotalBalance.js b/packages/hardhat/tasks/CLFScripts/src/pool/getTotalBalance.js deleted file mode 100644 index ffb27b914..000000000 --- a/packages/hardhat/tasks/CLFScripts/src/pool/getTotalBalance.js +++ /dev/null @@ -1,214 +0,0 @@ -(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_FUJI}']: { - // urls: [`https://avalanche-fuji.infura.io/v3/${secrets.INFURA_API_KEY}`], - // chainId: '0xa869', - // 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}', - // }, - - // 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}', - }, - }; - - const baseChainSelector = '${CL_CCIP_CHAIN_SELECTOR_BASE}'; - 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('${PARENT_POOL_PROXY_BASE}', poolAbi, baseProvider); - return pool.getDepositsOnTheWay(); - }; - - const getChildPoolsCcipLogs = async ccipLines => { - const ethersId = ethers.id('CCIPReceived(bytes32,uint64,address,address,uint256)'); - const promises = []; - - for (const chain in chainSelectors) { - const reqFromLines = ccipLines.filter(line => { - const hexChainSelector = `0x${BigInt(line.chainSelector).toString(16)}`.toLowerCase(); - return hexChainSelector === chain; - }); - const ethersId = ethers.id('ConceroChildPool_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 < reqFromLines.length && i < indexes[chainSelectorsKey] + 6; i++) { - promises.push( - provider.getLogs({ - address: chainSelectors[chainSelectorsKey].poolAddress, - topics: [ethersId, reqFromLines[i].ccipMessageId], - fromBlock: 0, - toBlock: 'latest', - }), - ); - } - indexes[chainSelectorsKey] = i; - } - - return await Promise.all(promises); - }; - - const logs1 = await getCcipLogs(); - await sleep(1000); - const logs2 = await getCcipLogs(); - await sleep(1000); - const logs3 = await getCcipLogs(); - - return logs1.concat(logs2).concat(logs3); - }; - - const getCompletedConceroIdsByLogs = (logs, ccipLines) => { - 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 < results.length - 2; i += 2) { - totalBalance += BigInt(results[i]) + BigInt(results[i + 1]); - } - - const depositsOnTheWayArray = results[results.length - 1]; - const depositsOnTheWay = depositsOnTheWayArray.reduce((acc, [chainSelector, ccipMessageId, amount], index) => { - 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); -})(); diff --git a/packages/hardhat/tasks/CLFScripts/src/pool/parentPoolEval.js b/packages/hardhat/tasks/CLFScripts/src/pool/parentPoolEval.js index 744b56058..691d5a61f 100644 --- a/packages/hardhat/tasks/CLFScripts/src/pool/parentPoolEval.js +++ b/packages/hardhat/tasks/CLFScripts/src/pool/parentPoolEval.js @@ -4,7 +4,7 @@ try { const q = 'https://raw.githubusercontent.com/concero/contracts-ccip/' + '${CLF_JS_CODE_BRANCH}' + - `/packages/hardhat/tasks/CLFScripts/dist/pool/${f === '0x02' ? 'collectLiquidity' : f === '0x01' ? 'distributeLiquidity' : 'getTotalBalance'}.min.js`; + `/packages/hardhat/tasks/CLFScripts/dist/pool/${f === '0x02' ? 'collectLiquidity' : f === '0x01' ? 'distributeLiquidity' : 'getChildPoolsLiquidity'}.min.js`; const [t, p] = await Promise.all([fetch(u), fetch(q)]); const [e, c] = await Promise.all([t.text(), p.text()]); const g = async s => {