Skip to content

Commit

Permalink
Merge branch 'main' into omahs-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
fionnachan authored Oct 13, 2023
2 parents 21b61a9 + 382dd9e commit 21d9faa
Show file tree
Hide file tree
Showing 9 changed files with 508 additions and 34 deletions.
12 changes: 11 additions & 1 deletion audit-ci.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
// Nodejs ‘undici’ Vulnerable to CRLF
// Used only in hardhat, so only in dev. Even then we dont use remote requests.
"GHSA-5r9g-qh6m-jxff",
// https://github.com/advisories/GHSA-j8xg-fqg3-53r7
// word-wrap vulnerable to Regular Expression Denial of Service
// Used only in eslint, so only in dev.
"GHSA-j8xg-fqg3-53r7",

// Open Zepplin
////////////
Expand Down Expand Up @@ -102,6 +106,12 @@
// from: @arbitrum/nitro-contracts>hardhat>semver
// from: arb-bridge-peripherals>arb-bridge-eth>hardhat>semver
// Used only in dev.
"GHSA-c2qf-rxjj-qqgw"
"GHSA-c2qf-rxjj-qqgw",
// https://github.com/advisories/GHSA-g4vp-m682-qqmp
// OpenZeppelin Contracts vulnerable to Improper Escaping of Output
// from: @arbitrum/nitro-contracts>@openzeppelin/contracts-upgradeable
// from @arbitrum/nitro-contracts>@openzeppelin/contracts
// We don't use ERC2771Context
"GHSA-g4vp-m682-qqmp"
]
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@arbitrum/sdk",
"version": "3.1.6",
"version": "3.1.12",
"description": "Typescript library client-side interactions with Arbitrum",
"author": "Offchain Labs, Inc.",
"license": "Apache-2.0",
Expand Down Expand Up @@ -49,6 +49,7 @@
"@ethersproject/address": "^5.0.8",
"@ethersproject/bignumber": "^5.1.1",
"@ethersproject/bytes": "^5.0.8",
"async-mutex": "^0.4.0",
"ethers": "^5.1.0"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export {
} from './lib/dataEntities/networks'
export { InboxTools } from './lib/inbox/inbox'
export { EventFetcher } from './lib/utils/eventFetcher'
export { ArbitrumProvider } from './lib/utils/arbProvider'
export * as constants from './lib/dataEntities/constants'
export { L2ToL1MessageStatus } from './lib/dataEntities/message'
export {
Expand Down
9 changes: 7 additions & 2 deletions src/lib/assetBridger/erc20Bridger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ export class Erc20Bridger extends AssetBridger<
gatewayAddress: string,
filter: { fromBlock: BlockTag; toBlock: BlockTag },
l1TokenAddress?: string,
fromAddress?: string
fromAddress?: string,
toAddress?: string
): Promise<(EventArgs<WithdrawalInitiatedEvent> & { txHash: string })[]> {
await this.checkL2Network(l2Provider)

Expand All @@ -306,7 +307,11 @@ export class Erc20Bridger extends AssetBridger<
await eventFetcher.getEvents(
L2ArbitrumGateway__factory,
contract =>
contract.filters.WithdrawalInitiated(null, fromAddress || null),
contract.filters.WithdrawalInitiated(
null, // l1Token
fromAddress || null, // _from
toAddress || null // _to
),
{ ...filter, address: gatewayAddress }
)
).map(a => ({ txHash: a.transactionHash, ...a.event }))
Expand Down
81 changes: 81 additions & 0 deletions src/lib/dataEntities/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ export const l1Networks: L1Networks = {
partnerChainIDs: [421613],
isArbitrum: false,
},
11155111: {
chainID: 11155111,
name: 'Sepolia',
explorerUrl: 'https://sepolia.etherscan.io',
partnerChainIDs: [421614],
blockTime: 12,
isCustom: false,
isArbitrum: false,
},
}

export const l2Networks: L2Networks = {
Expand Down Expand Up @@ -246,6 +255,78 @@ export const l2Networks: L2Networks = {
*/
depositTimeout: 1800000,
},
421614: {
chainID: 421614,
confirmPeriodBlocks: 20,
ethBridge: {
bridge: '0x38f918D0E9F1b721EDaA41302E399fa1B79333a9',
inbox: '0xaAe29B0366299461418F5324a79Afc425BE5ae21',
outbox: '0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F',
rollup: '0xd80810638dbDF9081b72C1B33c65375e807281C8',
sequencerInbox: '0x6c97864CE4bEf387dE0b3310A44230f7E3F1be0D',
},
explorerUrl: 'https://sepolia-explorer.arbitrum.io',
isArbitrum: true,
isCustom: false,
name: 'Arbitrum Rollup Sepolia Testnet',
partnerChainID: 11155111,
retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS,
tokenBridge: {
l1CustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3',
l1ERC20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF',
l1GatewayRouter: '0xcE18836b233C83325Cc8848CA4487e94C6288264',
l1MultiCall: '0xded9AD2E65F3c4315745dD915Dbe0A4Df61b2320',
l1ProxyAdmin: '0xDBFC2FfB44A5D841aB42b0882711ed6e5A9244b0',
l1Weth: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9',
l1WethGateway: '0xA8aD8d7e13cbf556eE75CB0324c13535d8100e1E',
l2CustomGateway: '0x8Ca1e1AC0f260BC4dA7Dd60aCA6CA66208E642C5',
l2ERC20Gateway: '0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502',
l2GatewayRouter: '0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7',
l2Multicall: '0xA115146782b7143fAdB3065D86eACB54c169d092',
l2ProxyAdmin: '0x715D99480b77A8d9D603638e593a539E21345FdF',
l2Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73',
l2WethGateway: '0xCFB1f08A4852699a979909e22c30263ca249556D',
},
nitroGenesisBlock: 0,
nitroGenesisL1Block: 0,
depositTimeout: 1800000,
},
23011913: {
chainID: 23011913,
confirmPeriodBlocks: 20,
ethBridge: {
bridge: '0x35aa95ac4747D928E2Cd42FE4461F6D9d1826346',
inbox: '0xe1e3b1CBaCC870cb6e5F4Bdf246feB6eB5cD351B',
outbox: '0x98fcA8bFF38a987B988E54273Fa228A52b62E43b',
rollup: '0x94db9E36d9336cD6F9FfcAd399dDa6Cc05299898',
sequencerInbox: '0x00A0F15b79d1D3e5991929FaAbCF2AA65623530c',
},
explorerUrl: 'https://stylus-testnet-explorer.arbitrum.io',
isArbitrum: true,
isCustom: false,
name: 'Stylus Testnet',
partnerChainID: 421614,
retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS,
tokenBridge: {
l1CustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415',
l1ERC20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B',
l1GatewayRouter: '0x0057892cb8bb5f1cE1B3C6f5adE899732249713f',
l1MultiCall: '0xBEbe3BfBF52FFEA965efdb3f14F2101c0264c940',
l1ProxyAdmin: '0xB9E77732f32831f09e2a50D6E71B2Cca227544bf',
l1Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73',
l1WethGateway: '0x39845e4a230434D218b907459a305eBA61A790d4',
l2CustomGateway: '0xF6dbB0e312dF4652d59ce405F5E00CC3430f19c5',
l2ERC20Gateway: '0xe027f79CE40a1eF8e47B51d0D46Dc4ea658C5860',
l2GatewayRouter: '0x4c3a1f7011F02Fe4769fC704359c3696a6A60D89',
l2Multicall: '0xEb4A260FD16aaf18c04B1aeaDFE20E622e549bd3',
l2ProxyAdmin: '0xE914c0d417E8250d0237d2F4827ed3612e6A9C3B',
l2Weth: '0x61Dc4b961D2165623A25EB775260785fE78BD37C',
l2WethGateway: '0x7021B4Edd9f047772242fc948441d6e0b9121175',
},
nitroGenesisBlock: 0,
nitroGenesisL1Block: 0,
depositTimeout: 900000,
},
}

const getNetwork = async (
Expand Down
92 changes: 88 additions & 4 deletions src/lib/message/L2ToL1MessageNitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory'

import { L2ToL1TxEvent } from '../abi/ArbSys'
import { ContractTransaction, Overrides } from 'ethers'
import { Mutex } from 'async-mutex'
import { EventFetcher, FetchedEvent } from '../utils/eventFetcher'
import { ArbSdkError } from '../dataEntities/errors'
import {
SignerProviderUtils,
SignerOrProvider,
} from '../dataEntities/signerOrProvider'
import { wait } from '../utils/lib'
import { getBlockRangesForL1Block, isArbitrumChain, wait } from '../utils/lib'
import { getL2Network } from '../dataEntities/networks'
import { NodeCreatedEvent, RollupUserLogic } from '../abi/RollupUserLogic'
import { ArbitrumProvider } from '../utils/arbProvider'
Expand All @@ -61,6 +62,64 @@ const ASSERTION_CREATED_PADDING = 50
// expected number of L1 blocks that it takes for a validator to confirm an L1 block after the node deadline is passed
const ASSERTION_CONFIRMED_PADDING = 20

const l2BlockRangeCache: { [key in string]: (number | undefined)[] } = {}
const mutex = new Mutex()

function getL2BlockRangeCacheKey({
l2ChainId,
l1BlockNumber,
}: {
l2ChainId: number
l1BlockNumber: number
}) {
return `${l2ChainId}-${l1BlockNumber}`
}

function setL2BlockRangeCache(key: string, value: (number | undefined)[]) {
l2BlockRangeCache[key] = value
}

async function getBlockRangesForL1BlockWithCache({
l1Provider,
l2Provider,
forL1Block,
}: {
l1Provider: JsonRpcProvider
l2Provider: JsonRpcProvider
forL1Block: number
}) {
const l2ChainId = (await l2Provider.getNetwork()).chainId
const key = getL2BlockRangeCacheKey({
l2ChainId,
l1BlockNumber: forL1Block,
})

if (l2BlockRangeCache[key]) {
return l2BlockRangeCache[key]
}

// implements a lock that only fetches cache once
const release = await mutex.acquire()

// if cache has been acquired while awaiting the lock
if (l2BlockRangeCache[key]) {
release()
return l2BlockRangeCache[key]
}

try {
const l2BlockRange = await getBlockRangesForL1Block({
forL1Block,
provider: l1Provider,
})
setL2BlockRangeCache(key, l2BlockRange)
} finally {
release()
}

return l2BlockRangeCache[key]
}

/**
* Base functionality for nitro L2->L1 messages
*/
Expand Down Expand Up @@ -204,16 +263,41 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro {
nodeNum: BigNumber,
l2Provider: Provider
): Promise<ArbBlock> {
const node = await rollup.getNode(nodeNum)
const { createdAtBlock } = await rollup.getNode(nodeNum)

let createdFromBlock = createdAtBlock
let createdToBlock = createdAtBlock

// If L1 is Arbitrum, then L2 is an Orbit chain.
if (await isArbitrumChain(this.l1Provider)) {
try {
const l2BlockRange = await getBlockRangesForL1BlockWithCache({
l1Provider: this.l1Provider as JsonRpcProvider,
l2Provider: l2Provider as JsonRpcProvider,
forL1Block: createdAtBlock.toNumber(),
})
const startBlock = l2BlockRange[0]
const endBlock = l2BlockRange[1]
if (!startBlock || !endBlock) {
throw new Error()
}
createdFromBlock = BigNumber.from(startBlock)
createdToBlock = BigNumber.from(endBlock)
} catch (e) {
// fallback to old method if the new method fails
createdFromBlock = createdAtBlock
createdToBlock = createdAtBlock
}
}

// now get the block hash and sendroot for that node
const eventFetcher = new EventFetcher(rollup.provider)
const logs = await eventFetcher.getEvents(
RollupUserLogic__factory,
t => t.filters.NodeCreated(nodeNum),
{
fromBlock: node.createdAtBlock.toNumber(),
toBlock: node.createdAtBlock.toNumber(),
fromBlock: createdFromBlock.toNumber(),
toBlock: createdToBlock.toNumber(),
address: rollup.address,
}
)
Expand Down
Loading

0 comments on commit 21d9faa

Please sign in to comment.