diff --git a/scripts/proposals/NovaFeeSweep/patchProposal.ts b/scripts/proposals/NovaFeeSweep/patchProposal.ts new file mode 100644 index 00000000..c2112d9a --- /dev/null +++ b/scripts/proposals/NovaFeeSweep/patchProposal.ts @@ -0,0 +1,66 @@ +// takes proposal data as input and adds a transaction to sweep ETH from the L1 Timelock alias on Nova +// context: https://www.tally.xyz/gov/arbitrum/proposal/108288822474129076868455956066667369439381709547570289793612729242368710728616 + +import { BigNumber, ethers } from 'ethers' +import { + IInbox__factory, + L1ArbitrumTimelock__factory, +} from '../../../typechain-types' +import { JsonRpcProvider } from '@ethersproject/providers' + +;(async () => { + // this is the bianca payload and serves as an example + // TODO: this should be replaced with some future proposal + const inputData = + '0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000000e13fb8241eb0e976305ff5f40d43d783c08468da55f38eee093510e004f512aa000000000000000000000000000000000000000000000000000000000003f48000000000000000000000000000000000000000000000000000000000000000070000000000000000000000003fffbadaf827559da092217e474760e2b2c3cedd0000000000000000000000003fffbadaf827559da092217e474760e2b2c3cedd000000000000000000000000a723c008e76e379c55599d2e4d93879beafda79c000000000000000000000000a723c008e76e379c55599d2e4d93879beafda79c000000000000000000000000a723c008e76e379c55599d2e4d93879beafda79c000000000000000000000000a723c008e76e379c55599d2e4d93879beafda79c000000000000000000000000a723c008e76e379c55599d2e4d93879beafda79c00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000074000000000000000000000000000000000000000000000000000000000000008e000000000000000000000000000000000000000000000000000000000000000841cff79cd00000000000000000000000019b715cf310c28c9020e53aaa11ce9df42e718b500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000841cff79cd000000000000000000000000658afc9d5ec4476fa6bb7033ea465f9901fbff2700000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f000000000000000000000000cf57572261c7c2bcf21ffd220ea7d1a27d40a82700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000841cff79cd000000000000000000000000af81c82ec98f86d0017d78cd66f1026f1a5cf1db00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f000000000000000000000000cf57572261c7c2bcf21ffd220ea7d1a27d40a82700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000841cff79cd000000000000000000000000b040b105a4a0c7a9cc290164accbc3285536832200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000c4448b71118c9071bcb9734a0eac55d18a15394900000000000000000000000086a02dd71363c440b21f4c0e5b2ad01ffe1a748200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000841cff79cd0000000000000000000000006dd43360d2a69bb9fffc5349f2511f2a3bcbc2da00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000c4448b71118c9071bcb9734a0eac55d18a15394900000000000000000000000086a02dd71363c440b21f4c0e5b2ad01ffe1a748200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000841cff79cd00000000000000000000000061703bf337341f2e09d96dd6488c2907718a8e2600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000c4448b71118c9071bcb9734a0eac55d18a15394900000000000000000000000086a02dd71363c440b21f4c0e5b2ad01ffe1a748200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000841cff79cd000000000000000000000000849e360a247132f961c9cbe95ba39106c72e126800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + + const l1TimelockAlias = '0xf7951d92b0c345144506576ec13ecf5103ac905a' + const novaInbox = '0xc4448b71118c9071Bcb9734A0EAc55D18A153949' + const novaToParentRouter = '0x36D0170D92F66e8949eB276C3AC4FEA64f83704d' + const maxL1GasPrice = ethers.utils.parseUnits('1000', 'gwei') // used to calculate maxSubmissionCost + const aliasBalance = await new JsonRpcProvider('https://nova.arbitrum.io/rpc').getBalance(l1TimelockAlias) + + const timelockIface = L1ArbitrumTimelock__factory.createInterface() + const inboxIface = IInbox__factory.createInterface() + + const maxSubmissionCost = calcSubmissionCost(maxL1GasPrice) + + const unsafeCreateRetryableCalldata = inboxIface.encodeFunctionData( + 'unsafeCreateRetryableTicket', + [ + novaToParentRouter, // to + aliasBalance.sub(maxSubmissionCost), // l2CallValue + maxSubmissionCost, // maxSubmissionCost + novaToParentRouter, // excessFeeRefundAddress + novaToParentRouter, // callValueRefundAddress + 0, // gasLimit + 0, // maxFeePerGas + '0x', // calldata + ] + ) + + const decodedScheduleBatch = timelockIface.decodeFunctionData( + 'scheduleBatch', + inputData + ) + + const patchedScheduleBatchCalldata = timelockIface.encodeFunctionData( + 'scheduleBatch', + [ + [...decodedScheduleBatch[0], novaInbox], + [...decodedScheduleBatch[1], 0], + [...decodedScheduleBatch[2], unsafeCreateRetryableCalldata], + decodedScheduleBatch[3], + decodedScheduleBatch[4], + decodedScheduleBatch[5], + ] + ) + + console.log(patchedScheduleBatchCalldata) +})() + +function calcSubmissionCost(baseFee: BigNumber) { + // data length is zero + // from the contract: return (1400 + 6 * dataLength) * (baseFee == 0 ? block.basefee : baseFee); + return baseFee.mul(1400) +}