From 62286546d9775afd57b0978b95b3971a6c20de81 Mon Sep 17 00:00:00 2001 From: Ameesha Agrawal Date: Sat, 29 Jun 2024 20:01:54 +0530 Subject: [PATCH 1/3] fix: gas limit estimate helpers --- scripts/socket-helpers/arb-estimate.ts | 37 ++++---------- scripts/socket-helpers/config.ts | 35 -------------- scripts/socket-helpers/main.ts | 37 ++++++++++++++ scripts/socket-helpers/opt-estimate.ts | 34 +++---------- scripts/socket-helpers/utils.ts | 67 ++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 91 deletions(-) delete mode 100644 scripts/socket-helpers/config.ts create mode 100644 scripts/socket-helpers/main.ts create mode 100644 scripts/socket-helpers/utils.ts diff --git a/scripts/socket-helpers/arb-estimate.ts b/scripts/socket-helpers/arb-estimate.ts index e8fbb5fae..831a9379c 100644 --- a/scripts/socket-helpers/arb-estimate.ts +++ b/scripts/socket-helpers/arb-estimate.ts @@ -1,24 +1,16 @@ -require("dotenv").config(); -import { utils, BigNumber, providers } from "ethers"; +import { utils, BigNumber } from "ethers"; import { ArbGasInfo__factory } from "@arbitrum/sdk/dist/lib/abi/factories/ArbGasInfo__factory"; import { NodeInterface__factory } from "@arbitrum/sdk/dist/lib/abi/factories/NodeInterface__factory"; import { ARB_GAS_INFO, NODE_INTERFACE_ADDRESS, } from "@arbitrum/sdk/dist/lib/dataEntities/constants"; -import { defaultAbiCoder } from "ethers/lib/utils"; -import { DeploymentMode, getAddresses } from "@socket.tech/dl-core"; -import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; -import { addresses, dstChainSlug, srcChainSlug } from "./config"; +import { TxData } from "./utils"; -const dstChainRPC = process.env.ARBITRUM_RPC; - -export const getArbitrumGasEstimate = async ( - amount: string, - receiver: string +export const getArbitrumGasLimitEstimate = async ( + provider, + txData: TxData ): Promise => { - const provider = new providers.StaticJsonRpcProvider(dstChainRPC); - const arbGasInfo = ArbGasInfo__factory.connect(ARB_GAS_INFO, provider); const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, @@ -26,29 +18,18 @@ export const getArbitrumGasEstimate = async ( ); // Getting the gas prices from ArbGasInfo.getPricesInWei() const gasComponents = await arbGasInfo.callStatic.getPricesInWei(); - - const payload = defaultAbiCoder.encode( - ["address", "uint256"], - [receiver, amount] - ); - const abiInterface = new utils.Interface(PlugABI); - const txData = abiInterface.encodeFunctionData("inbound", [ - srcChainSlug, - payload, - ]); - const gasEstimateComponents = await nodeInterface.callStatic.gasEstimateComponents( - addresses[dstChainSlug].USDC.connectors[srcChainSlug].FAST, + txData.to, false, - txData, - { from: getAddresses(dstChainSlug, DeploymentMode.PROD).Socket } + txData.data, + { from: txData.from } ); const l2GasUsed = gasEstimateComponents.gasEstimate.sub( gasEstimateComponents.gasEstimateForL1 ); - const L1S = 140 + utils.hexDataLength(txData); + const L1S = 140 + utils.hexDataLength(txData.data); const L1C = gasComponents[1].mul(L1S); const B = L1C.div(gasComponents[5]); diff --git a/scripts/socket-helpers/config.ts b/scripts/socket-helpers/config.ts deleted file mode 100644 index 7a658a513..000000000 --- a/scripts/socket-helpers/config.ts +++ /dev/null @@ -1,35 +0,0 @@ -export const addresses = { - "10": { - USDC: { - connectors: { - "2999": { - FAST: "0x1812ff6bd726934f18159164e2927B34949B16a8", - }, - }, - }, - }, - "2999": { - USDC: { - connectors: { - "10": { - FAST: "0x7b9ed5C43E87DAFB03211651d4FA41fEa1Eb9b3D", - }, - "42161": { - FAST: "0x73019b64e31e699fFd27d54E91D686313C14191C", - }, - }, - }, - }, - "42161": { - USDC: { - connectors: { - "2999": { - FAST: "0x69Adf49285c25d9f840c577A0e3cb134caF944D3", - }, - }, - }, - }, -}; - -export const srcChainSlug = 2999; -export const dstChainSlug = 42161; diff --git a/scripts/socket-helpers/main.ts b/scripts/socket-helpers/main.ts new file mode 100644 index 000000000..a61202fda --- /dev/null +++ b/scripts/socket-helpers/main.ts @@ -0,0 +1,37 @@ +require("dotenv").config(); +import { BigNumber, providers, utils } from "ethers"; +import { DeploymentMode, } from "@socket.tech/dl-core"; +import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; + +import { ChainDetails, Inputs, getPayload } from "./utils"; +import { getJsonRpcUrl } from "../constants"; +import { ChainSlug, arbChains, arbL3Chains, getAddresses } from "../../src"; +import { getArbitrumGasLimitEstimate } from "./arb-estimate"; +import { getOptimismGasLimitEstimate } from "./opt-estimate"; + +export const getEstimatedGasLimit = async ( + chainDetails: ChainDetails, + inputs: Inputs, + withoutHook?: boolean +): Promise => { + const srcChainSlug = chainDetails.srcChainSlug as ChainSlug; + const dstChainSlug = chainDetails.dstChainSlug as ChainSlug; + + const provider = new providers.StaticJsonRpcProvider(getJsonRpcUrl(dstChainSlug)); + const payload = getPayload(inputs, inputs.connectorPlug, provider, withoutHook); + + const abiInterface = new utils.Interface(PlugABI); + const data = abiInterface.encodeFunctionData("inbound", [ + srcChainSlug, + payload, + ]); + + const txData = { + from: getAddresses(dstChainSlug, DeploymentMode.PROD).Socket, + to: inputs.connectorPlug, + data + } + if (arbChains.includes(chainDetails.dstChainSlug) || arbL3Chains.includes(chainDetails.dstChainSlug)) { + return await getArbitrumGasLimitEstimate(provider, txData) + } else return await getOptimismGasLimitEstimate(provider, txData) +}; diff --git a/scripts/socket-helpers/opt-estimate.ts b/scripts/socket-helpers/opt-estimate.ts index cd7c4ad37..2fbddbfda 100644 --- a/scripts/socket-helpers/opt-estimate.ts +++ b/scripts/socket-helpers/opt-estimate.ts @@ -1,35 +1,13 @@ -require("dotenv").config(); -import { BigNumber, providers, utils } from "ethers"; +import { BigNumber } from "ethers"; import { asL2Provider } from "@eth-optimism/sdk"; -import { defaultAbiCoder } from "ethers/lib/utils"; -import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; -import { addresses, dstChainSlug, srcChainSlug } from "./config"; -import { DeploymentMode, getAddresses } from "@socket.tech/dl-core"; - -const dstChainRPC = process.env.OPTIMISM_RPC; +import { TxData } from "./utils"; // Get optimism gas limit from the SDK -export const getOptimismGasEstimate = async ( - amount: string, - receiver: string +export const getOptimismGasLimitEstimate = async ( + provider, + txData: TxData ): Promise => { - const provider = new providers.StaticJsonRpcProvider(dstChainRPC); const l2Provider = asL2Provider(provider); - - const payload = defaultAbiCoder.encode( - ["address", "uint256"], - [receiver, amount] - ); - const abiInterface = new utils.Interface(PlugABI); - const data = abiInterface.encodeFunctionData("inbound", [ - srcChainSlug, - payload, - ]); - - const gasLimit = await l2Provider.estimateGas({ - data, - to: addresses[dstChainSlug].USDC.connectors[srcChainSlug].FAST, - from: getAddresses(dstChainSlug, DeploymentMode.PROD).Socket, - }); + const gasLimit = await l2Provider.estimateGas(txData); return gasLimit; }; diff --git a/scripts/socket-helpers/utils.ts b/scripts/socket-helpers/utils.ts new file mode 100644 index 000000000..3716afd98 --- /dev/null +++ b/scripts/socket-helpers/utils.ts @@ -0,0 +1,67 @@ +import { Contract, utils } from "ethers"; +import { defaultAbiCoder } from "ethers/lib/utils"; +import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; + +export type TxData = { + from: string, + to: string, + data: string +} + +export type Inputs = { + amount: string; + receiver: string; + executionData: string; + connectorPlug: string; +}; + +export type ChainDetails = { + srcChainSlug: number; + dstChainSlug: number; +} + +export const abiInterface = new utils.Interface(PlugABI); + +const ConnectorABI = [ + { + inputs: [], + name: "getMessageId", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, +]; + +export const getPayload = async ( + inputs: Inputs, + connectorAddress: string, + provider, + withoutHook?: boolean +) => { + let payload; + if (withoutHook) { + payload = defaultAbiCoder.encode( + ["address", "uint256"], + [inputs.receiver, inputs.amount] + ); + } else { + const connectorContract = new Contract( + connectorAddress, + ConnectorABI, + provider + ); + const msgId = await connectorContract.getMessageId(); + payload = defaultAbiCoder.encode( + ["address", "uint256", "bytes32", "bytes"], + [inputs.receiver, inputs.amount, msgId, inputs.executionData] + ); + } + + return payload; +}; From a5362e8760fe2bee98f27bfd7d750ef2915565a8 Mon Sep 17 00:00:00 2001 From: Ameesha Agrawal Date: Sat, 29 Jun 2024 20:02:06 +0530 Subject: [PATCH 2/3] fix: lint --- scripts/socket-helpers/main.ts | 52 ++++++++++++++++++++------------- scripts/socket-helpers/utils.ts | 10 +++---- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/scripts/socket-helpers/main.ts b/scripts/socket-helpers/main.ts index a61202fda..d93ee5d89 100644 --- a/scripts/socket-helpers/main.ts +++ b/scripts/socket-helpers/main.ts @@ -1,6 +1,6 @@ require("dotenv").config(); import { BigNumber, providers, utils } from "ethers"; -import { DeploymentMode, } from "@socket.tech/dl-core"; +import { DeploymentMode } from "@socket.tech/dl-core"; import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; import { ChainDetails, Inputs, getPayload } from "./utils"; @@ -10,28 +10,38 @@ import { getArbitrumGasLimitEstimate } from "./arb-estimate"; import { getOptimismGasLimitEstimate } from "./opt-estimate"; export const getEstimatedGasLimit = async ( - chainDetails: ChainDetails, - inputs: Inputs, - withoutHook?: boolean + chainDetails: ChainDetails, + inputs: Inputs, + withoutHook?: boolean ): Promise => { - const srcChainSlug = chainDetails.srcChainSlug as ChainSlug; - const dstChainSlug = chainDetails.dstChainSlug as ChainSlug; + const srcChainSlug = chainDetails.srcChainSlug as ChainSlug; + const dstChainSlug = chainDetails.dstChainSlug as ChainSlug; - const provider = new providers.StaticJsonRpcProvider(getJsonRpcUrl(dstChainSlug)); - const payload = getPayload(inputs, inputs.connectorPlug, provider, withoutHook); + const provider = new providers.StaticJsonRpcProvider( + getJsonRpcUrl(dstChainSlug) + ); + const payload = getPayload( + inputs, + inputs.connectorPlug, + provider, + withoutHook + ); - const abiInterface = new utils.Interface(PlugABI); - const data = abiInterface.encodeFunctionData("inbound", [ - srcChainSlug, - payload, - ]); + const abiInterface = new utils.Interface(PlugABI); + const data = abiInterface.encodeFunctionData("inbound", [ + srcChainSlug, + payload, + ]); - const txData = { - from: getAddresses(dstChainSlug, DeploymentMode.PROD).Socket, - to: inputs.connectorPlug, - data - } - if (arbChains.includes(chainDetails.dstChainSlug) || arbL3Chains.includes(chainDetails.dstChainSlug)) { - return await getArbitrumGasLimitEstimate(provider, txData) - } else return await getOptimismGasLimitEstimate(provider, txData) + const txData = { + from: getAddresses(dstChainSlug, DeploymentMode.PROD).Socket, + to: inputs.connectorPlug, + data, + }; + if ( + arbChains.includes(chainDetails.dstChainSlug) || + arbL3Chains.includes(chainDetails.dstChainSlug) + ) { + return await getArbitrumGasLimitEstimate(provider, txData); + } else return await getOptimismGasLimitEstimate(provider, txData); }; diff --git a/scripts/socket-helpers/utils.ts b/scripts/socket-helpers/utils.ts index 3716afd98..8ad238427 100644 --- a/scripts/socket-helpers/utils.ts +++ b/scripts/socket-helpers/utils.ts @@ -3,10 +3,10 @@ import { defaultAbiCoder } from "ethers/lib/utils"; import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; export type TxData = { - from: string, - to: string, - data: string -} + from: string; + to: string; + data: string; +}; export type Inputs = { amount: string; @@ -18,7 +18,7 @@ export type Inputs = { export type ChainDetails = { srcChainSlug: number; dstChainSlug: number; -} +}; export const abiInterface = new utils.Interface(PlugABI); From 6026bfe46611ebe402e9a19a33f77322a58c7192 Mon Sep 17 00:00:00 2001 From: Ameesha Agrawal Date: Wed, 3 Jul 2024 14:04:49 +0530 Subject: [PATCH 3/3] fix: types and comments --- scripts/socket-helpers/arb-estimate.ts | 9 ++++- scripts/socket-helpers/main.ts | 37 +++++++++++++------ .../{opt-estimate.ts => op-n-eth-estimate.ts} | 5 ++- scripts/socket-helpers/utils.ts | 11 +++--- 4 files changed, 42 insertions(+), 20 deletions(-) rename scripts/socket-helpers/{opt-estimate.ts => op-n-eth-estimate.ts} (68%) diff --git a/scripts/socket-helpers/arb-estimate.ts b/scripts/socket-helpers/arb-estimate.ts index 831a9379c..ca67a480f 100644 --- a/scripts/socket-helpers/arb-estimate.ts +++ b/scripts/socket-helpers/arb-estimate.ts @@ -6,9 +6,10 @@ import { NODE_INTERFACE_ADDRESS, } from "@arbitrum/sdk/dist/lib/dataEntities/constants"; import { TxData } from "./utils"; +import { StaticJsonRpcProvider } from "@ethersproject/providers"; export const getArbitrumGasLimitEstimate = async ( - provider, + provider: StaticJsonRpcProvider, txData: TxData ): Promise => { const arbGasInfo = ArbGasInfo__factory.connect(ARB_GAS_INFO, provider); @@ -29,8 +30,14 @@ export const getArbitrumGasLimitEstimate = async ( const l2GasUsed = gasEstimateComponents.gasEstimate.sub( gasEstimateComponents.gasEstimateForL1 ); + + // Size in bytes of the calldata to post on L1 const L1S = 140 + utils.hexDataLength(txData.data); + + // Estimated L1 gas cost const L1C = gasComponents[1].mul(L1S); + + // Extra buffer const B = L1C.div(gasComponents[5]); // G (Gas Limit) = l2GasUsed + B diff --git a/scripts/socket-helpers/main.ts b/scripts/socket-helpers/main.ts index d93ee5d89..9fbd54d33 100644 --- a/scripts/socket-helpers/main.ts +++ b/scripts/socket-helpers/main.ts @@ -5,27 +5,22 @@ import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; import { ChainDetails, Inputs, getPayload } from "./utils"; import { getJsonRpcUrl } from "../constants"; -import { ChainSlug, arbChains, arbL3Chains, getAddresses } from "../../src"; +import { arbChains, arbL3Chains, getAddresses } from "../../src"; import { getArbitrumGasLimitEstimate } from "./arb-estimate"; -import { getOptimismGasLimitEstimate } from "./opt-estimate"; +import { getOpAndEthGasLimitEstimate } from "./op-n-eth-estimate"; -export const getEstimatedGasLimit = async ( +export const main = async ( chainDetails: ChainDetails, inputs: Inputs, withoutHook?: boolean ): Promise => { - const srcChainSlug = chainDetails.srcChainSlug as ChainSlug; - const dstChainSlug = chainDetails.dstChainSlug as ChainSlug; + const srcChainSlug = chainDetails.srcChainSlug; + const dstChainSlug = chainDetails.dstChainSlug; const provider = new providers.StaticJsonRpcProvider( getJsonRpcUrl(dstChainSlug) ); - const payload = getPayload( - inputs, - inputs.connectorPlug, - provider, - withoutHook - ); + const payload = await getPayload(inputs, provider, withoutHook); const abiInterface = new utils.Interface(PlugABI); const data = abiInterface.encodeFunctionData("inbound", [ @@ -38,10 +33,28 @@ export const getEstimatedGasLimit = async ( to: inputs.connectorPlug, data, }; + if ( arbChains.includes(chainDetails.dstChainSlug) || arbL3Chains.includes(chainDetails.dstChainSlug) ) { return await getArbitrumGasLimitEstimate(provider, txData); - } else return await getOptimismGasLimitEstimate(provider, txData); + } else { + // works for opt and eth like chains + return await getOpAndEthGasLimitEstimate(provider, txData); + } }; + +main( + { + srcChainSlug: 42161, + dstChainSlug: 1324967486, + }, + { + amount: "2000000000", + connectorPlug: "0x663dc7e91157c58079f55c1bf5ee1bdb6401ca7a", + executionData: "0x", + receiver: "0x663dc7e91157c58079f55c1bf5ee1bdb6401ca7a", + }, + false +); diff --git a/scripts/socket-helpers/opt-estimate.ts b/scripts/socket-helpers/op-n-eth-estimate.ts similarity index 68% rename from scripts/socket-helpers/opt-estimate.ts rename to scripts/socket-helpers/op-n-eth-estimate.ts index 2fbddbfda..b7806187b 100644 --- a/scripts/socket-helpers/opt-estimate.ts +++ b/scripts/socket-helpers/op-n-eth-estimate.ts @@ -1,10 +1,11 @@ import { BigNumber } from "ethers"; +import { StaticJsonRpcProvider } from "@ethersproject/providers"; import { asL2Provider } from "@eth-optimism/sdk"; import { TxData } from "./utils"; // Get optimism gas limit from the SDK -export const getOptimismGasLimitEstimate = async ( - provider, +export const getOpAndEthGasLimitEstimate = async ( + provider: StaticJsonRpcProvider, txData: TxData ): Promise => { const l2Provider = asL2Provider(provider); diff --git a/scripts/socket-helpers/utils.ts b/scripts/socket-helpers/utils.ts index 8ad238427..cd3cbb1b9 100644 --- a/scripts/socket-helpers/utils.ts +++ b/scripts/socket-helpers/utils.ts @@ -1,6 +1,8 @@ import { Contract, utils } from "ethers"; import { defaultAbiCoder } from "ethers/lib/utils"; +import { StaticJsonRpcProvider } from "@ethersproject/providers"; import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; +import { ChainSlug } from "../../src"; export type TxData = { from: string; @@ -16,8 +18,8 @@ export type Inputs = { }; export type ChainDetails = { - srcChainSlug: number; - dstChainSlug: number; + srcChainSlug: ChainSlug; + dstChainSlug: ChainSlug; }; export const abiInterface = new utils.Interface(PlugABI); @@ -40,8 +42,7 @@ const ConnectorABI = [ export const getPayload = async ( inputs: Inputs, - connectorAddress: string, - provider, + provider: StaticJsonRpcProvider, withoutHook?: boolean ) => { let payload; @@ -52,7 +53,7 @@ export const getPayload = async ( ); } else { const connectorContract = new Contract( - connectorAddress, + inputs.connectorPlug, ConnectorABI, provider );