From fd8df14e77308d34aa5b7780a6d0c00bf747382a Mon Sep 17 00:00:00 2001 From: xiaohuo Date: Thu, 2 May 2024 01:58:04 +0800 Subject: [PATCH 1/3] feat: script for setting orbit chain base gas --- src/setL2BaseFee.ts | 119 ++++++++++++++++++++++++++ src/setL2BaseFeeEncodeFunctionData.ts | 17 ++++ 2 files changed, 136 insertions(+) create mode 100644 src/setL2BaseFee.ts create mode 100644 src/setL2BaseFeeEncodeFunctionData.ts diff --git a/src/setL2BaseFee.ts b/src/setL2BaseFee.ts new file mode 100644 index 00000000..1f9a32b2 --- /dev/null +++ b/src/setL2BaseFee.ts @@ -0,0 +1,119 @@ +import { PublicClient, WalletClient } from 'viem'; +import { getContract } from 'viem'; +import { validateParentChain } from './types/ParentChain'; +import L1AtomicTokenBridgeCreator from '@arbitrum/token-bridge-contracts/build/contracts/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol/L1AtomicTokenBridgeCreator.json'; +import { Interface } from 'ethers/lib/utils'; +import { upgradeExecutor } from './contracts'; +import { getAddress } from 'viem'; +import { + setL2BaseFeeEnocdeFunctionData, + setMinimumL2BaseFeeEnocdeFunctionData, +} from './setL2BaseFeeEncodeFunctionData'; + +export type BaseFeeParams = { + parentChainClient: PublicClient; + orbitChainClient: PublicClient; + orbitChainWalletClient: WalletClient; + tokenBridgeCreatorAddress: `0x${string}`; + inboxAddress: `0x${string}`; +}; + +export type SetL2BaseFeeParams = { + l2BaseFee: string; +}; + +export type SetMinimumL2BaseFeeParams = { + minimumL2BaseFee: string; +}; + +const arbOwner = '0x0000000000000000000000000000000000000070'; + +export async function setL2BaseFee({ + parentChainClient, + orbitChainClient, + orbitChainWalletClient, + tokenBridgeCreatorAddress, + inboxAddress, + l2BaseFee, +}: BaseFeeParams & SetL2BaseFeeParams) { + validateParentChain(parentChainClient); + const account = orbitChainWalletClient.account?.address; + + if (typeof account === 'undefined') { + throw new Error('account is undefined'); + } + + const upgradeExecutorProxyAddress = await getUpgradeExecutorProxyAddress( + tokenBridgeCreatorAddress, + inboxAddress, + orbitChainClient, + ); + + const { request } = await orbitChainClient.simulateContract({ + address: getAddress(upgradeExecutorProxyAddress), + abi: upgradeExecutor.abi, + functionName: 'executeCall', + args: [ + arbOwner, // target + setL2BaseFeeEnocdeFunctionData(BigInt(l2BaseFee)), // targetCallData + ], + account, + }); + + const hash = await orbitChainWalletClient.writeContract(request); + const txReceipt = await orbitChainClient.waitForTransactionReceipt({ hash }); + + return txReceipt; +} + +export async function setMinimumL2BaseFee({ + parentChainClient, + orbitChainClient, + orbitChainWalletClient, + tokenBridgeCreatorAddress, + inboxAddress, + minimumL2BaseFee, +}: BaseFeeParams & SetMinimumL2BaseFeeParams) { + validateParentChain(parentChainClient); + const account = orbitChainWalletClient.account?.address; + + if (typeof account === 'undefined') { + throw new Error('account is undefined'); + } + + const upgradeExecutorProxyAddress = await getUpgradeExecutorProxyAddress( + tokenBridgeCreatorAddress, + inboxAddress, + orbitChainClient, + ); + + const { request } = await orbitChainClient.simulateContract({ + address: getAddress(upgradeExecutorProxyAddress), + abi: upgradeExecutor.abi, + functionName: 'executeCall', + args: [ + arbOwner, // target + setMinimumL2BaseFeeEnocdeFunctionData(BigInt(minimumL2BaseFee)), // targetCallData + ], + account, + }); + + const hash = await orbitChainWalletClient.writeContract(request); + const txReceipt = await orbitChainClient.waitForTransactionReceipt({ hash }); + + return txReceipt; +} + +async function getUpgradeExecutorProxyAddress( + tokenBridgeCreatorAddress: `0x${string}`, + inboxAddress: `0x${string}`, + publicClient: PublicClient, +): Promise<`0x${string}`> { + const tokenBridgeCreator = getContract({ + address: tokenBridgeCreatorAddress, + abi: L1AtomicTokenBridgeCreator.abi, + publicClient: publicClient, + }); + const deployment: any = await tokenBridgeCreator.read.inboxToL2Deployment([inboxAddress]); + return deployment.upgradeExecutor as `0x${string}`; +} diff --git a/src/setL2BaseFeeEncodeFunctionData.ts b/src/setL2BaseFeeEncodeFunctionData.ts new file mode 100644 index 00000000..780f3bd4 --- /dev/null +++ b/src/setL2BaseFeeEncodeFunctionData.ts @@ -0,0 +1,17 @@ +import { encodeFunctionData, parseAbi } from 'viem'; + +export function setL2BaseFeeEnocdeFunctionData(priceInWei: bigint) { + return encodeFunctionData({ + abi: parseAbi(['function setL2BaseFee(uint256 priceInWei)']), + functionName: 'setL2BaseFee', + args: [priceInWei], + }); +} + +export function setMinimumL2BaseFeeEnocdeFunctionData(priceInWei: bigint) { + return encodeFunctionData({ + abi: parseAbi(['function setMinimumL2BaseFee(uint256 priceInWei)']), + functionName: 'setMinimumL2BaseFee', + args: [priceInWei], + }); +} From 0de25e72a734fb2e06107e637a7c6aefdf3566d5 Mon Sep 17 00:00:00 2001 From: xiaohuo Date: Thu, 2 May 2024 01:58:49 +0800 Subject: [PATCH 2/3] chore: clean import --- src/setL2BaseFee.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/setL2BaseFee.ts b/src/setL2BaseFee.ts index 1f9a32b2..cee63086 100644 --- a/src/setL2BaseFee.ts +++ b/src/setL2BaseFee.ts @@ -2,7 +2,6 @@ import { PublicClient, WalletClient } from 'viem'; import { getContract } from 'viem'; import { validateParentChain } from './types/ParentChain'; import L1AtomicTokenBridgeCreator from '@arbitrum/token-bridge-contracts/build/contracts/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol/L1AtomicTokenBridgeCreator.json'; -import { Interface } from 'ethers/lib/utils'; import { upgradeExecutor } from './contracts'; import { getAddress } from 'viem'; import { From 01fd9f2633fc8f8281853ad39b4fe13c6384cce5 Mon Sep 17 00:00:00 2001 From: xiaohuo Date: Sun, 12 May 2024 22:30:04 +0800 Subject: [PATCH 3/3] refactor: use arbOwner decorators --- src/setL2BaseFee.ts | 66 ++++++++++++--------------- src/setL2BaseFeeEncodeFunctionData.ts | 17 ------- 2 files changed, 30 insertions(+), 53 deletions(-) delete mode 100644 src/setL2BaseFeeEncodeFunctionData.ts diff --git a/src/setL2BaseFee.ts b/src/setL2BaseFee.ts index cee63086..64e82192 100644 --- a/src/setL2BaseFee.ts +++ b/src/setL2BaseFee.ts @@ -2,12 +2,8 @@ import { PublicClient, WalletClient } from 'viem'; import { getContract } from 'viem'; import { validateParentChain } from './types/ParentChain'; import L1AtomicTokenBridgeCreator from '@arbitrum/token-bridge-contracts/build/contracts/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol/L1AtomicTokenBridgeCreator.json'; -import { upgradeExecutor } from './contracts'; -import { getAddress } from 'viem'; -import { - setL2BaseFeeEnocdeFunctionData, - setMinimumL2BaseFeeEnocdeFunctionData, -} from './setL2BaseFeeEncodeFunctionData'; +import { arbOwnerPublicActions } from './decorators/arbOwnerPublicActions'; +import { arbGasInfoPublicActions } from './decorators/arbGasInfoPublicActions'; export type BaseFeeParams = { parentChainClient: PublicClient; @@ -18,15 +14,13 @@ export type BaseFeeParams = { }; export type SetL2BaseFeeParams = { - l2BaseFee: string; + l2BaseFee: bigint; }; export type SetMinimumL2BaseFeeParams = { - minimumL2BaseFee: string; + minimumL2BaseFee: bigint; }; -const arbOwner = '0x0000000000000000000000000000000000000070'; - export async function setL2BaseFee({ parentChainClient, orbitChainClient, @@ -42,27 +36,27 @@ export async function setL2BaseFee({ throw new Error('account is undefined'); } + const extendedOrbitChainClient = orbitChainClient + .extend(arbOwnerPublicActions) + .extend(arbGasInfoPublicActions); + const upgradeExecutorProxyAddress = await getUpgradeExecutorProxyAddress( tokenBridgeCreatorAddress, inboxAddress, orbitChainClient, ); - const { request } = await orbitChainClient.simulateContract({ - address: getAddress(upgradeExecutorProxyAddress), - abi: upgradeExecutor.abi, - functionName: 'executeCall', - args: [ - arbOwner, // target - setL2BaseFeeEnocdeFunctionData(BigInt(l2BaseFee)), // targetCallData - ], - account, + const transactionRequest = await extendedOrbitChainClient.arbOwnerPrepareTransactionRequest({ + functionName: 'setL2BaseFee', + args: [l2BaseFee], + upgradeExecutor: upgradeExecutorProxyAddress, + account: account, }); - const hash = await orbitChainWalletClient.writeContract(request); - const txReceipt = await orbitChainClient.waitForTransactionReceipt({ hash }); - - return txReceipt; + // submit tx to set l2 base fee + return await extendedOrbitChainClient.sendRawTransaction({ + serializedTransaction: await orbitChainWalletClient.signTransaction(transactionRequest), + }); } export async function setMinimumL2BaseFee({ @@ -80,27 +74,27 @@ export async function setMinimumL2BaseFee({ throw new Error('account is undefined'); } + const extendedOrbitChainClient = orbitChainClient + .extend(arbOwnerPublicActions) + .extend(arbGasInfoPublicActions); + const upgradeExecutorProxyAddress = await getUpgradeExecutorProxyAddress( tokenBridgeCreatorAddress, inboxAddress, orbitChainClient, ); - const { request } = await orbitChainClient.simulateContract({ - address: getAddress(upgradeExecutorProxyAddress), - abi: upgradeExecutor.abi, - functionName: 'executeCall', - args: [ - arbOwner, // target - setMinimumL2BaseFeeEnocdeFunctionData(BigInt(minimumL2BaseFee)), // targetCallData - ], - account, + const transactionRequest = await extendedOrbitChainClient.arbOwnerPrepareTransactionRequest({ + functionName: 'setMinimumL2BaseFee', + args: [minimumL2BaseFee], + upgradeExecutor: upgradeExecutorProxyAddress, + account: account, }); - const hash = await orbitChainWalletClient.writeContract(request); - const txReceipt = await orbitChainClient.waitForTransactionReceipt({ hash }); - - return txReceipt; + // submit tx to set minimum l2 base fee + return await extendedOrbitChainClient.sendRawTransaction({ + serializedTransaction: await orbitChainWalletClient.signTransaction(transactionRequest), + }); } async function getUpgradeExecutorProxyAddress( diff --git a/src/setL2BaseFeeEncodeFunctionData.ts b/src/setL2BaseFeeEncodeFunctionData.ts deleted file mode 100644 index 780f3bd4..00000000 --- a/src/setL2BaseFeeEncodeFunctionData.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { encodeFunctionData, parseAbi } from 'viem'; - -export function setL2BaseFeeEnocdeFunctionData(priceInWei: bigint) { - return encodeFunctionData({ - abi: parseAbi(['function setL2BaseFee(uint256 priceInWei)']), - functionName: 'setL2BaseFee', - args: [priceInWei], - }); -} - -export function setMinimumL2BaseFeeEnocdeFunctionData(priceInWei: bigint) { - return encodeFunctionData({ - abi: parseAbi(['function setMinimumL2BaseFee(uint256 priceInWei)']), - functionName: 'setMinimumL2BaseFee', - args: [priceInWei], - }); -}