Skip to main content

Release notes

Beta v1a

Mainnet: TBC

Linea Sepolia: September 26

Beta v1 on Linea introduces new arithmetization, and is split into two phases:

  1. Beta v1a: Transition to the new arithmetization, and;
  2. Beta v1b: Ensure the new arithmetization is 100% proven.

The overall objective of the Linea Beta is to prove 100% of the zkEVM specification.

This release includes:

  • New arithmetization, with selected modules activated from the Linea specification.
  • The transition to generating traces with Besu.

Alpha v4

Mainnet: December 10, 2024

Linea Sepolia: November 27, 2024

This update upgrades several key contracts. Some updates prepare the protocol for the ability to reconstruct the Linea state, while others add granularity to available roles, better preparing them for any required pauses. Many of the contract modifications have also resulted in gas optimizations.

Additionally, we are removing the finalizeBlocksWithoutProof function, and adding functionality that enables any address to send blob submission and finalization transactions through a call forwarding contract if no finalization occurs for more than six months. This effectively allows L1 finalization, enabling withdrawal of potentially locked funds.

  • Adjust blob submission and finalization events to be state reconstruction-compatible
    • This is a breaking change for the event structures. The new structures are below:
    /**
    * @notice Emitted when compressed data is being submitted and verified succesfully on L1.
    * @dev The block range is indexed and parent shnarf included for state reconstruction simplicity.
    * @param parentShnarf The parent shnarf for the data being submitted.
    * @param shnarf The indexed shnarf for the data being submitted.
    * @param finalStateRootHash The L2 state root hash that the current blob submission ends on. NB: The last blob in the collection.
    */
    event DataSubmittedV3(bytes32 parentShnarf, bytes32 indexed shnarf, bytes32 finalStateRootHash);

    /**
    * @notice Emitted when L2 blocks have been finalized on L1.
    * @param startBlockNumber The indexed L2 block number indicating which block the finalization the data starts from.
    * @param endBlockNumber The indexed L2 block number indicating which block the finalization the data ends on.
    * @param shnarf The indexed shnarf being set as currentFinalizedShnarf in the current finalization.
    * @param parentStateRootHash The parent L2 state root hash that the current finalization starts from.
    * @param finalStateRootHash The L2 state root hash that the current finalization ends on.
    */
    event DataFinalizedV3(
    uint256 indexed startBlockNumber,
    uint256 indexed endBlockNumber,
    bytes32 indexed shnarf,
    bytes32 parentStateRootHash,
    bytes32 finalStateRootHash
    );
    • DataSubmittedV2 becomes DataSubmittedV3, DataFinalized becomes DataFinalizedV3 (DataFinalizedV2 was skipped to align version numbers).
    • The change also introduced gas optimizations for blob submission and finalization.
  • Create granular roles for contracts LineaRollup, L2MessageService and TokenBridge:
    • LineaRollup: Introduce more granular pausing and an additional verifier unsetting role
    • L2MessageService: Introduce more granular pausing
    • TokenBridge: Previously all administration functions were managed by a single owner (multisig) role. The update adds role-based access with more granular roles per function, particularly for pausing.
  • Remove finalizeBlocksWithoutProof function
    • The function enabled finalization without proofs. This allowed network activity to continue while fundamental changes, such as changing the state management hashing mechanism, were being made. This is the only time the function was used, and it was primarily retained as a contingency.
  • Allow any address to finalize blocks if no finalization has occurred in the last six months
    • Add functionality to the LineaRollup contract to allow any address to submit valid blobs and valid finalization proofs, generated by running the Linea stack locally, to withdraw funds from L2. The mechanism only works if no finalization has happened for six months. The system is intended as a contingency.
    • The change enables the LineaRollup contract to grant a "fallback operator" the OPERATOR_ROLE required to submit the blobs and finalization proofs. The "fallback operator" is a message forwarding contract enabling any address to submit this data.
  • Bump L1 Solidity version to v0.8.26. Introduces slight gas optimizations.
  • Optimize message and new token creation hashing, making it slightly cheaper to send and claim messages.
  • Address non-critical findings from previous audit rounds:
  • Generally clean up error management and interfaces.

Alpha v3.6

Block size changes

Mainnet: September 25

Linea Sepolia: September 25

Increase block limit to 30M units of gas. The transaction limit remains at 24M. Block time also remains the same, at 2 seconds.

Alpha v3.5.2

Transaction exclusion API

Mainnet: September 23

Linea Sepolia: September 18

Introduces an API that can be used to check whether a transaction was rejected because it exceeded the sequencer's trace limits.

Alpha v3.5.1

Linea native bridge UI v2

Mainnet: September 18

Linea Sepolia: September 18

Upgrades the Linea bridge UI.

Alpha v3.5.0

finalized tag

Mainnet: October 9

Linea Sepolia: September 17

Adds support for the finalized tag to the blockParameters strings that can be used in various JSON-RPC API calls. The tag enables you to confirm whether or not a block has been finalized on L1. See our guide for more.

Alpha v3.4.1

Reactivate linea_estimateGas

Mainnet: September 30

Linea Sepolia: September 9

Reactivates linea_estimateGas, disabling compatibility mode.

Alpha v3.4

Mainnet and Testnet: July 30

ENS on Linea

Adds support for Linea ENS domains, including a frontend app for users to register and manage their domains. The Linea ENS system is comparable to ENS on Ethereum Mainnet, except that domains are limited to one per account and registering requires completion of Proof of Humanity. As the system leverages CCIP Read, which enables L1 to trustlessly query the Linea ENS registry through an offchain gateway, Linea ENS domains resolve on L1.

Read more about ENS in the user guide here.

CCIP Read

One of the building blocks of ENS on Linea is a custom implementation of CCIP Read, which uses the gateway system introduced in EIP-3668 to enable Linea ENS names to resolve on L1. The key contracts created by ENS have been adjusted by the Linea team to ensure they work with Linea's Sparse Merkle Tree system.

The CCIP Read functionality can be applied to any context where a L1 protocol may benefit from securely querying data on Linea. See our page on CCIP Read for more information and guidance on how to use the relevant contracts.

The Linea repository containing the relevant contracts is here.

Consensys Diligence carried out an audit on Linea ENS, available here.

linea_estimateGas mainnet activation

note

Available on Linea Sepolia on July 31; available on Mainnet from August 1.

Activates the linea_estimateGas endpoint for use on Mainnet in compatibility mode.

See our reference page for more information and usage.

Alpha v3.3

Testnet: June 3

Mainnet: June 11, 10:00 UTC

Breaking change: block time and block size reduction

Reducing block time to 2 seconds, with a target block size of 24M gas.

The change will increase transaction throughput by approximately 20%, improving user experience by making Linea faster and more responsive.

Actions recommended for node runners

We recommend you adjust your node configurations to ensure any submitted transactions are handled in line with the sequencer.

Besu:

In the besu-sequencer plugin, adjust:

  • plugin-linea-max-tx-gas-limit to 24000000
  • plugin-linea-max-block-gas to 24000000

Geth:

  • In the config .toml file, set [Eth]RPCGasCap to 24000000
    • Or use —-rpc.gascap in the command line, again specifying 24000000

Alpha v3.2

Testnet: May 28

Mainnet: June 4

Smart contract gas optimization

Upgraded smart contracts to achieve gas optimizations in several areas:

  • Major gas optimizations in blob submission, primarily in LineaRollup.sol
  • Finalization
  • The token bridge.

The upgrade commit is available here.

Code in the upgrade has been audited by:

  • OpenZeppelin, whose report is available here, and;
  • Cyfrin, whose report is here.

Bridge to a different recipient

note

May 29: Fully functional on testnet; ETH and USDC supported on mainnet.

June 4: Fully functional on mainnet.

The Linea bridge has been upgraded to enable recipient addresses to always be able to claim bridged funds. Bridge transfers to alternative recipients (i.e. an address that isn't the sender's address) now appear on the recipient's "Recent transactions" list, enabling them to claim.

These changes have been audited by OpenZeppelin and Cyfrin.

Alpha v3.1

Mainnet: May 14

  • Introduces dynamic L1 gwei thresholds for submitting data to L1 for finalization.
  • Adds the eth_sendRawTransaction method, available only via Besu endpoints.

Alpha v3

Summary

The main objective of Alpha v3 is to implement EIP-4844 on Linea, following its introduction to Ethereum mainnet with the Dencun upgrade on March 13.

Features

March 26: EIP-4844

Begin using blobs to post compressed L2 data to L1, with the aim of reducing data availability costs. Blobs represent a transient data storage mechanism and an alternative to calldata, and can be significantly cheaper in L1 ETH costs depending on market demand.

Learn more about EIP-4844

EIP-4844's arrival on Ethereum Mainnet enabled Ethereum L2s to start using a new transaction type that transports L2 transaction and messaging data to L1 in "blobs". Blobs are a considerably more cost-efficient alternative to the existing method of posting L2 transaction and messaging data to L1, which involved sending calldata embedded in a transaction.

With Alpha v3, L2 transaction data is added to blobs. The savings generated by using blobs rather than calldata mainly derive from avoiding the highly competitive L1 gas fee market.

Since transactions containing calldata have to compete with regular L1 transactions for block space, L2s are vulnerable to L1 network congestion and the fee spikes it can generate. Before the transition to using blobs, L1 data availability—i.e. the cost of posting data to L1 in calldata—made up more than 95% of the gas costs on Linea.

Conversely, blobs have their own fee market, completely separate to the regular gas fee market on L1. As a result, L2s like Linea now have an alternative to paying regular gas fees, and can instead compete for blob space.

Due to having an entirely new market designed for L2 data availability, the cost of using blobs will be a fraction of the cost of using calldata.

L1 and L2 smart contracts have been updated and deployed for Alpha v3. The contract addresses are:

Smart contract updates will be executed by the Linea Security Council using the Safe multi-sig procedure.

Additionally, all contracts have been audited by OpenZeppelin. You can find the report here.

March 27

  • Block time reduced to 3 seconds. This change increases the throughput of the network to avoid any potential L2 execution bottlenecks from increased Linea activity.
  • Gas fee reductions. After EIP-4844 was implemented on March 26, we monitored data for 24 hours before reducing gas fees for all users on March 27.

Breaking changes

None.

February 2024

February 19

Testnet:

  • Released a higher priced version of linea_estimateGas (this will change once the endpoint is fully functional)

Mainnet:

  • Released a higher priced version of linea_estimateGas (this will change once the endpoint is fully functional)

February 12

Testnet:

  • Updated Bridge UI to v0.5.4 to support the new claiming method via Linea SDK v0.2.1

Mainnet:

  • Updated Bridge UI to v0.5.4 to support the new claiming method via Linea SDK v0.2.1

February 5

Testnet:

  • Deployed Linea Gas API to estimate how much gas is necessary to be included and published on Ethereum.
note

Learn how to use the Linea Gas API here.

Alpha v2

NetworkTarget Release Date
MainnetFebruary 13th, 2024
TestnetJanuary 24, 2024

Summary

This release focuses on reducing L1 costs, enabling lower prices for end users.

L1 costs are primarily driven by the following:

  • Proof verification, which is essentially a fixed cost for every batch submission.

  • Hashing the batch submission data to produce the public input of the Plonk verifier.

  • Calldata costs, driven by the size of the batch submission data. This includes all the transaction data from L2, as well as messaging data (one hash per L2 to L1 message).

Features

To decrease L1 costs, we implemented the following features:

  • Proof aggregation:
    • This allows us to create a set of execution proofs for conflated batches and generates an aggregated proof that verifies that all the batches are correct. Since it takes the same amount of gas to verify an aggregated proof vs. a proof for a single batch of conflated blocks, the average cost of verifying a proof aggregating N proofs is N times cheaper.
Learn more about proof aggregation

Generating a zkSNARK proof on L1 is an essential step for finalizing transactions, as a verified proof demonstrates the integrity and validity of the submitted transactions.

Previously, Linea generated one proof per batch of transactions. After Alpha v2, Linea began to recursively aggregate multiple proofs into one.

The verification process on L1 costs ~400,000 gas — a cost that previously had to be covered for every batch. This gas cost is the same, however, for verifying a single batch of conflated batches (as Linea did in Alpha v1) as it is for verifying an aggregated proof representing multiple batches (as in Alpha v2). A proof that aggregates N proofs is N times cheaper, as the cost remains consistent.

With Alpha v2 upgrades, Linea now averages ~30 batches per final proof, making the process 1/30th as costly as it was in Alpha v1.

  • Data compression:
    • This reduces the call data cost on L1 by compressing L2 block data. (Post EIP-4844 this will be stored in blobs)
Learn more about data compression

Data compression significantly reduces the cost of posting L2 transaction and messaging data to L1.

The system leverages the Linea prover's ability to operate with a compressed input, meaning it can decompress calldata or blob data to validate L2 state transitions. The data passed to the L1 smart contract can therefore be considerably smaller, driving down the sum cost of transactions in each block.

The data compression algorithm is completely lossless, and can achieve compression ratios of up to 15:1 (where the data is 15 times smaller than its uncompressed state). This affords Linea the ability to submit data about far more transactions in each batch: before Alpha v2, Linea averaged ~150 transactions per batch; afterwards, it averages ~1,500.

As a result, significantly more transactions can be processed for the same computational cost on L1. The combination of blobs and data compression further amplifies the gas fee savings that are passed on to Linea users.

  • Switched L2 to L1 messaging anchoring from individual hashes to Merkle trees:
    • Due to the size of the Merkle trees (32 messages) requiring only one Merkle root to be anchored, there is a 32x calldata size reduction for message hashes

Smart contract changes

To support these new features, we implemented changes to our smart contracts.

We introduce a VERIFIER_SETTER_ROLE, that will be attributed to the Timelock.sol so that all core contract upgrades (Rollup and Message and Token bridge) and verifiers are executed through a TimeLock mechanism. Note that we are also using this upgrade to update the way the type 2 state was calculated; as such we'll need to call finalizeWithoutProof to perform a state transition from type2 state v1 to type2 state v2.

The Security Council will first execute the following transactions on L1:

  • Assign Operator Role via the Safe to the account for blob submission
  • Assign Verifier Setter role via the Safe to the Timelock
  • Schedule Set new Verifier at index 0
  • Execute Set new Verifier at index 0
  • Schedule LineaRollup upgrade (at L1 block N)
  • Execute LineaRollup upgrade (at L1 block N)
  • Update Zodiac delegate roles from pauseByType(bytes32) -> pauseByType(uint8)

The Security Council will then execute the following transactions on L2:

  • Schedule L2MessageService upgrade
  • Execute L2MessageService upgrade

Post upgrade, Execute the following Security Council transactions on L1:

  • Call FinalizeWithoutProof
  • Clear verifier mapping at index 6 and 7

The audited commit for this update can be found here.

Two independent audits have been performed for this update. Reports can be found here:

Breaking changes

Message claiming

  • Parties claiming messages on Layer 1 will need to adjust claiming behavior to account for Merkle Proof generation requests and their submission when claiming a message. This applies to messages sent post upgrading. Pre-existing messages must be claimed with the current approach.
Note

If you are using the Linea Bridge UI, then this is already done for you. If you are a partner/user who manages their claiming outside of the Bridge UI, then we recommend looking at the updated SDK.

Finalization events

  • After migration to the new finalization mechanism, the rollup contract will no longer emit finalization events per block, but will instead emit events for data submission as well as an event indicating the current point of finalization.
    • The calldata will contain only the final block state root hash and final block number.
Note

This is a breaking change for consumers listening to the existing events. The BlockFinalized event will be replaced by the DataFinalized event.

EventDescriptionStatus
DataFinalized

Emitted at the end of finalization - used to indicate range of finalization

New
BlockFinalized

Deprecated finalization event - indicator that each block has been finalized.

Old

December 2023

December 11

Testnet:

  • Transitioned the sequencer to Besu from Geth

Mainnet:

  • Fixes to the Linea bridge UI:
    • Users are now redirected to MetaMask Mobile when attempting to access the bridge on a mobile browser
    • Default token list now refreshes on every load rather than being stored locally; only the user's custom tokens are stored

December 4

Testnet:

  • Fixes to the Linea bridge UI:
    • Users are now redirected to MetaMask Mobile when attempting to access the bridge on a mobile browser
    • Default token list now refreshes on every load rather than being stored locally; only the user's custom tokens are stored

Mainnet:

  • Lowered block time to 6 seconds

November 2023

November 27

Testnet:

  • Upgrades to the official Linea bridge:
    • UI updated to display tokens from the official token list
    • Improved page to redirect most users to MetaMask Portfolio to bridge

Mainnet:

  • Upgrades to the official Linea bridge:
    • UI updated to display tokens from the official token list
    • Improved page to redirect most users to MetaMask Portfolio to bridge

November 13

Testnet:

  • Lowered block time to 6 seconds
  • Updated default gasPrice to 3 Gwei

Mainnet:

  • Increased block size from 60KB to 109KB
  • Deployed the Linea Voyage XP (LXP) token contract
  • Lowered block time to 8 seconds
  • Updated default gasPrice to 3 Gwei

October 2023

October 23

Testnet:

  • Increased block size limit from 70KB to 109KB

Summary release notes (June - October)

Performance improvements

  • Changes to the Genesis File: We made changes to the genesis file to enable block times to be reduced. This enhancement improves the overall performance and throughput of Linea.

  • Improved Gas Limit Estimation for Finalization on L1: We improved the gas limit estimation for finalization on L1.

Cost efficiency

  • We updated the L1 message service contract to work with the Merkle tree, reducing gas costs and further enhancing the cost-effectiveness of Linea.

  • We added a fixed cost to the gas price to cover infrastructure costs for system economic sustainability. This change ensures the long-term financial viability of Linea.

User experience

  • We smoothed the L2 gas price estimation by using an L1 moving average. This update makes our gas price estimation more accurate and reliable.

Linea Alpha v0.2.3 (June 22, 2023)

Summary

This release focuses on optimizing the prover's hashing strategy to increase its computational efficiency.

Linea Alpha v0.2.2 (June 20, 2023)

Summary

This release focuses on updating the Postman SDK configuration values and revising gas fee calculations.

Features

  • Updated the Postman SDK configuration files to handle messages that are contract calls with zero ETH value being transferred and revised gas fee calculations.

Linea Alpha v0.2.1 (June 15, 2023)

Summary

This release reduces the gas cost of submitting a batch of transactions on L1 by optimizing L2 logs in the calldata that is sent to L1.

Features

  • Instead of sending the entire event MessageSent, we only send the _messageHash field of the event.

  • Old calldata for L2 originated event:

    //		event MessageSent(
    // address indexed _from,
    // address indexed _to,
    // uint256 _fee,
    // uint256 _value,
    // uint256 _salt,
    // bytes _calldata,
    // bytes32 _messageHash
    // );
  • New calldata for L2 originated event:

      //			bytes32 _messageHash

Linea Alpha v0.2.0 (June 13, 2023)

Summary

This release focuses on testing a substantial architecture upgrade in preparation for Mainnet launch. It contains multiple improvements and breaking changes, specifically around the messaging layer which is changed to a push model. It also improves EVM prover coverage, and provides batch conflation.

Features

  • Add Batch Conflation feature to the sequencer to minimize L1 transactions cost.
    • With Batch Conflation, L2 blocks' proofs that should have been independent are instead merged together. Therefore, L1 costs for these blocks’ proofs are divided by the number of merged blocks.
  • Improve the following smart contracts:
    • Rollup zkEVM: Upgrade the rollup main contract with support for
      • Conflation
      • Security Council management
      • Verifier
      • Messaging Service
        • Changed the message service model by splitting the delivery into anchoring and claiming of messages to allow more flexible workflows, remove the mandatory fee for L1→L2, reduce the mandatory fee for L2→L1
    • Canonical Token Bridge: Upgrade from 1-1 ERC-20 basic token bridge to N-N ERC-20 canonical token bridge with reservation and token registry
  • Add Postman Service for message execution
    • The Postman Service is Linea’s off-chain message delivery service. It’s decentralized, permissionless, and used to claim messages once the protocol has anchored the message hashes. The first release will only contain the following scenarios:
      • DApps/protocols operating the SDK (to be released) claiming messages and paying for gas
        • The protocol can filter messages based on origin or destination smart-contracts
      • Linea operating the SDK for dApps/Protocols that aren’t yet integrated
    • If messages don’t get delivered by the postman, the message can be manually claimed by calling claimMessage with the MessageSent event parameters or by using the SDK.
  • Update prover to integrate with the new architecture and support Batch Conflation

Breaking changes

Message bridge

  • Bridging partners will need to listen to different events. Modifications to the events are seen below:

    EventDescription
    L1MessageClaimedWhen a message is claimed
    L1L1L2MessagesReceivedOnL2

    Message hashes have been anchored on L2 and the zkRollup updates the L1 statuses - Includes multiple message hashes

    L1L2L1MessageHashAddedToInbox

    The L2 message hash has been anchored on L1 and can be claimed on block finalization.

    L2MessageSentEmitted when a message is sent
    L2MessageClaimedEmitted when a message is claimed
    L2L1L2MessageHashesAddedToInbox

    L1→L2 message hash has been anchored on L2 and can be claimed on block finalization.

  • The anchoring and execution (claim) process has been separated into 2 steps. The deadline concept has been completely removed.

note

Contracts audit is in progress. This doesn't reflect final versions.

  • L1 (Goerli):

    • Bridging partners, to send messages, will need to call the new contract address with a different ABI.

      zkEVM2.abi
      [
      {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
      },
      {
      "inputs": [],
      "name": "BlockTimestampError",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "EmptyBlock",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "recipient",
      "type": "address"
      }
      ],
      "name": "FeePaymentFailed",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "FeeTooLow",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "InvalidProof",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "InvalidProofType",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "pauseType",
      "type": "bytes32"
      }
      ],
      "name": "IsPaused",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "messageHash",
      "type": "bytes32"
      }
      ],
      "name": "L1L2MessageNotSent",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "LimitIsZero",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "MessageAlreadyClaimed",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "messageHash",
      "type": "bytes32"
      }
      ],
      "name": "MessageAlreadyReceived",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "MessageAlreadySent",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "destination",
      "type": "address"
      }
      ],
      "name": "MessageSendingFailed",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "PeriodIsZero",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ProofIsEmpty",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "RateLimitExceeded",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "StartingRootHashDoesNotMatch",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ValueSentTooLow",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ValueShouldBeGreaterThanFee",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ZeroAddressNotAllowed",
      "type": "error"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "address",
      "name": "resettingAddress",
      "type": "address"
      }
      ],
      "name": "AmountUsedInPeriodReset",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "uint256",
      "name": "blockNumber",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "stateRootHash",
      "type": "bytes32"
      }
      ],
      "name": "BlockFinalized",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "uint256",
      "name": "lastBlockFinalized",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "startingRootHash",
      "type": "bytes32"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "finalRootHash",
      "type": "bytes32"
      }
      ],
      "name": "BlocksVerificationDone",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "uint8",
      "name": "version",
      "type": "uint8"
      }
      ],
      "name": "Initialized",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "messageHash",
      "type": "bytes32"
      }
      ],
      "name": "L1L2MessageHashAddedToOutbox",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "bytes32[]",
      "name": "messageHashes",
      "type": "bytes32[]"
      }
      ],
      "name": "L1L2MessagesReceivedOnL2",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "messageHash",
      "type": "bytes32"
      }
      ],
      "name": "L2L1MessageClaimed",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "messageHash",
      "type": "bytes32"
      }
      ],
      "name": "L2L1MessageHashAddedToInbox",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "address",
      "name": "amountChangeBy",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "amount",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "bool",
      "name": "amountUsedLoweredToLimit",
      "type": "bool"
      }
      ],
      "name": "LimitAmountChange",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "_messageHash",
      "type": "bytes32"
      }
      ],
      "name": "MessageClaimed",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "address",
      "name": "_from",
      "type": "address"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "_to",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "_value",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "_nonce",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "bytes",
      "name": "_calldata",
      "type": "bytes"
      },
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "_messageHash",
      "type": "bytes32"
      }
      ],
      "name": "MessageSent",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "address",
      "name": "messageSender",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "pauseType",
      "type": "bytes32"
      }
      ],
      "name": "Paused",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "previousAdminRole",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "newAdminRole",
      "type": "bytes32"
      }
      ],
      "name": "RoleAdminChanged",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "account",
      "type": "address"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "sender",
      "type": "address"
      }
      ],
      "name": "RoleGranted",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "account",
      "type": "address"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "sender",
      "type": "address"
      }
      ],
      "name": "RoleRevoked",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "address",
      "name": "messageSender",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "pauseType",
      "type": "bytes32"
      }
      ],
      "name": "UnPaused",
      "type": "event"
      },
      {
      "inputs": [],
      "name": "DEFAULT_ADMIN_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "GENERAL_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "INBOX_STATUS_RECEIVED",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "INBOX_STATUS_UNKNOWN",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "L1_L2_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "L2_L1_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "OUTBOX_STATUS_RECEIVED",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "OUTBOX_STATUS_SENT",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "OUTBOX_STATUS_UNKNOWN",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "PAUSE_MANAGER_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "PROVING_SYSTEM_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "RATE_LIMIT_SETTER_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_limitManagerAddress",
      "type": "address"
      },
      {
      "internalType": "address",
      "name": "_pauseManagerAddress",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_rateLimitPeriod",
      "type": "uint256"
      },
      {
      "internalType": "uint256",
      "name": "_rateLimitAmount",
      "type": "uint256"
      }
      ],
      "name": "__MessageService_init",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_from",
      "type": "address"
      },
      {
      "internalType": "address",
      "name": "_to",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      },
      {
      "internalType": "uint256",
      "name": "_value",
      "type": "uint256"
      },
      {
      "internalType": "address payable",
      "name": "_feeRecipient",
      "type": "address"
      },
      {
      "internalType": "bytes",
      "name": "_calldata",
      "type": "bytes"
      },
      {
      "internalType": "uint256",
      "name": "_nonce",
      "type": "uint256"
      }
      ],
      "name": "claimMessage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "currentL2BlockNumber",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "currentPeriodAmountInWei",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "currentPeriodEnd",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "currentTimestamp",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "components": [
      {
      "internalType": "bytes32",
      "name": "blockRootHash",
      "type": "bytes32"
      },
      {
      "internalType": "uint32",
      "name": "l2BlockTimestamp",
      "type": "uint32"
      },
      {
      "internalType": "bytes[]",
      "name": "transactions",
      "type": "bytes[]"
      },
      {
      "internalType": "bytes[]",
      "name": "l2l1logs",
      "type": "bytes[]"
      },
      {
      "internalType": "uint16[]",
      "name": "batchReceptionIndices",
      "type": "uint16[]"
      }
      ],
      "internalType": "struct IZkEvmV2.BlockData[]",
      "name": "_blocksData",
      "type": "tuple[]"
      },
      {
      "internalType": "bytes",
      "name": "_proof",
      "type": "bytes"
      },
      {
      "internalType": "uint256",
      "name": "_proofType",
      "type": "uint256"
      },
      {
      "internalType": "bytes32",
      "name": "_parentStateRootHash",
      "type": "bytes32"
      }
      ],
      "name": "finalizeBlocks",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "components": [
      {
      "internalType": "bytes32",
      "name": "blockRootHash",
      "type": "bytes32"
      },
      {
      "internalType": "uint32",
      "name": "l2BlockTimestamp",
      "type": "uint32"
      },
      {
      "internalType": "bytes[]",
      "name": "transactions",
      "type": "bytes[]"
      },
      {
      "internalType": "bytes[]",
      "name": "l2l1logs",
      "type": "bytes[]"
      },
      {
      "internalType": "uint16[]",
      "name": "batchReceptionIndices",
      "type": "uint16[]"
      }
      ],
      "internalType": "struct IZkEvmV2.BlockData[]",
      "name": "_blocksData",
      "type": "tuple[]"
      }
      ],
      "name": "finalizeBlocksWithoutProof",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      }
      ],
      "name": "getRoleAdmin",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "grantRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "hasRole",
      "outputs": [
      {
      "internalType": "bool",
      "name": "",
      "type": "bool"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "name": "inboxL2L1MessageStatus",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "_initialStateRootHash",
      "type": "bytes32"
      },
      {
      "internalType": "uint256",
      "name": "_initialL2BlockNumber",
      "type": "uint256"
      },
      {
      "internalType": "address",
      "name": "_defaultVerifier",
      "type": "address"
      },
      {
      "internalType": "address",
      "name": "_securityCouncil",
      "type": "address"
      },
      {
      "internalType": "address[]",
      "name": "_operators",
      "type": "address[]"
      },
      {
      "internalType": "uint256",
      "name": "_rateLimitPeriodInSeconds",
      "type": "uint256"
      },
      {
      "internalType": "uint256",
      "name": "_rateLimitAmountInWei",
      "type": "uint256"
      }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "limitInWei",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "nextMessageNumber",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "name": "outboxL1L2MessageStatus",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "_pauseType",
      "type": "bytes32"
      }
      ],
      "name": "pauseByType",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "name": "pauseTypeStatuses",
      "outputs": [
      {
      "internalType": "bool",
      "name": "",
      "type": "bool"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "periodInSeconds",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "renounceRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "resetAmountUsedInPeriod",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "uint256",
      "name": "_amount",
      "type": "uint256"
      }
      ],
      "name": "resetRateLimitAmount",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "revokeRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_to",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      },
      {
      "internalType": "bytes",
      "name": "_calldata",
      "type": "bytes"
      }
      ],
      "name": "sendMessage",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "sender",
      "outputs": [
      {
      "internalType": "address",
      "name": "",
      "type": "address"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_newVerifierAddress",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_proofType",
      "type": "uint256"
      }
      ],
      "name": "setVerifierAddress",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "name": "stateRootHashes",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes4",
      "name": "interfaceId",
      "type": "bytes4"
      }
      ],
      "name": "supportsInterface",
      "outputs": [
      {
      "internalType": "bool",
      "name": "",
      "type": "bool"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "_pauseType",
      "type": "bytes32"
      }
      ],
      "name": "unPauseByType",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "name": "verifiers",
      "outputs": [
      {
      "internalType": "address",
      "name": "",
      "type": "address"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "stateMutability": "payable",
      "type": "receive"
      }
      ]
    • Contracts:

  • L2 (Linea):

    • Bridging partners, to send messages, will need to call the new contract address with a different ABI.

      L2MessageService.abi
      [
      {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
      },
      {
      "inputs": [],
      "name": "EmptyMessageHashesArray",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "recipient",
      "type": "address"
      }
      ],
      "name": "FeePaymentFailed",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "FeeTooLow",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "pauseType",
      "type": "bytes32"
      }
      ],
      "name": "IsPaused",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "LimitIsZero",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "MessageAlreadyClaimed",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "uint256",
      "name": "length",
      "type": "uint256"
      }
      ],
      "name": "MessageHashesListLengthHigherThanOneHundred",
      "type": "error"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "destination",
      "type": "address"
      }
      ],
      "name": "MessageSendingFailed",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "PeriodIsZero",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "RateLimitExceeded",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ValueSentTooLow",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ValueShouldBeGreaterThanFee",
      "type": "error"
      },
      {
      "inputs": [],
      "name": "ZeroAddressNotAllowed",
      "type": "error"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "address",
      "name": "resettingAddress",
      "type": "address"
      }
      ],
      "name": "AmountUsedInPeriodReset",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "uint8",
      "name": "version",
      "type": "uint8"
      }
      ],
      "name": "Initialized",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "messageHash",
      "type": "bytes32"
      }
      ],
      "name": "L1L2MessageClaimed",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "bytes32[]",
      "name": "messageHashes",
      "type": "bytes32[]"
      }
      ],
      "name": "L1L2MessageHashesAddedToInbox",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "address",
      "name": "amountChangeBy",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "amount",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "bool",
      "name": "amountUsedLoweredToLimit",
      "type": "bool"
      }
      ],
      "name": "LimitAmountChange",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "_messageHash",
      "type": "bytes32"
      }
      ],
      "name": "MessageClaimed",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "address",
      "name": "_from",
      "type": "address"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "_to",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "_value",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "uint256",
      "name": "_nonce",
      "type": "uint256"
      },
      {
      "indexed": false,
      "internalType": "bytes",
      "name": "_calldata",
      "type": "bytes"
      },
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "_messageHash",
      "type": "bytes32"
      }
      ],
      "name": "MessageSent",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "address",
      "name": "messageSender",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "pauseType",
      "type": "bytes32"
      }
      ],
      "name": "Paused",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "previousAdminRole",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "newAdminRole",
      "type": "bytes32"
      }
      ],
      "name": "RoleAdminChanged",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "account",
      "type": "address"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "sender",
      "type": "address"
      }
      ],
      "name": "RoleGranted",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": true,
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "account",
      "type": "address"
      },
      {
      "indexed": true,
      "internalType": "address",
      "name": "sender",
      "type": "address"
      }
      ],
      "name": "RoleRevoked",
      "type": "event"
      },
      {
      "anonymous": false,
      "inputs": [
      {
      "indexed": false,
      "internalType": "address",
      "name": "messageSender",
      "type": "address"
      },
      {
      "indexed": false,
      "internalType": "bytes32",
      "name": "pauseType",
      "type": "bytes32"
      }
      ],
      "name": "UnPaused",
      "type": "event"
      },
      {
      "inputs": [],
      "name": "DEFAULT_ADMIN_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "GENERAL_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "INBOX_STATUS_CLAIMED",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "INBOX_STATUS_RECEIVED",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "INBOX_STATUS_UNKNOWN",
      "outputs": [
      {
      "internalType": "uint8",
      "name": "",
      "type": "uint8"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "L1_L2_MESSAGE_SETTER_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "L1_L2_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "L2_L1_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "MINIMUM_FEE_SETTER_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "PAUSE_MANAGER_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "PROVING_SYSTEM_PAUSE_TYPE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "RATE_LIMIT_SETTER_ROLE",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_l1l2MessageSetter",
      "type": "address"
      }
      ],
      "name": "__L2MessageManager_init",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32[]",
      "name": "_messageHashes",
      "type": "bytes32[]"
      }
      ],
      "name": "addL1L2MessageHashes",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_from",
      "type": "address"
      },
      {
      "internalType": "address",
      "name": "_to",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      },
      {
      "internalType": "uint256",
      "name": "_value",
      "type": "uint256"
      },
      {
      "internalType": "address payable",
      "name": "_feeRecipient",
      "type": "address"
      },
      {
      "internalType": "bytes",
      "name": "_calldata",
      "type": "bytes"
      },
      {
      "internalType": "uint256",
      "name": "_nonce",
      "type": "uint256"
      }
      ],
      "name": "claimMessage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "currentPeriodAmountInWei",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "currentPeriodEnd",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      }
      ],
      "name": "getRoleAdmin",
      "outputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "grantRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "hasRole",
      "outputs": [
      {
      "internalType": "bool",
      "name": "",
      "type": "bool"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "name": "inboxL1L2MessageStatus",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_securityCouncil",
      "type": "address"
      },
      {
      "internalType": "address",
      "name": "_l1l2MessageSetter",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_rateLimitPeriod",
      "type": "uint256"
      },
      {
      "internalType": "uint256",
      "name": "_rateLimitAmount",
      "type": "uint256"
      }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "limitInWei",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "minimumFee",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "nextMessageNumber",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "_pauseType",
      "type": "bytes32"
      }
      ],
      "name": "pauseByType",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "",
      "type": "bytes32"
      }
      ],
      "name": "pauseTypeStatuses",
      "outputs": [
      {
      "internalType": "bool",
      "name": "",
      "type": "bool"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "periodInSeconds",
      "outputs": [
      {
      "internalType": "uint256",
      "name": "",
      "type": "uint256"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "renounceRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "resetAmountUsedInPeriod",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "uint256",
      "name": "_amount",
      "type": "uint256"
      }
      ],
      "name": "resetRateLimitAmount",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "role",
      "type": "bytes32"
      },
      {
      "internalType": "address",
      "name": "account",
      "type": "address"
      }
      ],
      "name": "revokeRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "address",
      "name": "_to",
      "type": "address"
      },
      {
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      },
      {
      "internalType": "bytes",
      "name": "_calldata",
      "type": "bytes"
      }
      ],
      "name": "sendMessage",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
      },
      {
      "inputs": [],
      "name": "sender",
      "outputs": [
      {
      "internalType": "address",
      "name": "",
      "type": "address"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "uint256",
      "name": "_fee",
      "type": "uint256"
      }
      ],
      "name": "setMinimumFee",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes4",
      "name": "interfaceId",
      "type": "bytes4"
      }
      ],
      "name": "supportsInterface",
      "outputs": [
      {
      "internalType": "bool",
      "name": "",
      "type": "bool"
      }
      ],
      "stateMutability": "view",
      "type": "function"
      },
      {
      "inputs": [
      {
      "internalType": "bytes32",
      "name": "_pauseType",
      "type": "bytes32"
      }
      ],
      "name": "unPauseByType",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
      },
      {
      "stateMutability": "payable",
      "type": "receive"
      }
      ]
    • Contracts

      • Transparent Proxy: 0xC499a572640B64eA1C8c194c43Bc3E19940719dC
      • Implementation: 0xc0557e2149751e201749b87f86acd91DB22e2662
  • Bridging partners, before sending messages on L2, need to retrieve the service protection fee before sending messages and include it in the value sent.

Canonical Token Bridge

Major changes are applied to the Canonical Token Bridge as described in our documentation.

  • L1 (Goerli)

    TokenBridge.abi
    [
    {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "AlreadyBridgedToken",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "bytes4",
    "name": "permitData",
    "type": "bytes4"
    },
    {
    "internalType": "bytes32",
    "name": "permitSelector",
    "type": "bytes32"
    }
    ],
    "name": "InvalidPermitData",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "sender",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "tokenBridge",
    "type": "address"
    }
    ],
    "name": "NotFromRemoteTokenBridge",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "sender",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "messageService",
    "type": "address"
    }
    ],
    "name": "NotMessagingService",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "NotReserved",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "spender",
    "type": "address"
    }
    ],
    "name": "PermitNotAllowingBridge",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "owner",
    "type": "address"
    }
    ],
    "name": "PermitNotFromSender",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "remoteTokenBridge",
    "type": "address"
    }
    ],
    "name": "RemoteTokenBridgeAlreadySet",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "ReservedToken",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "TokenNotDeployed",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "addr",
    "type": "address"
    }
    ],
    "name": "ZeroAddressNotAllowed",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "uint256",
    "name": "amount",
    "type": "uint256"
    }
    ],
    "name": "ZeroAmountNotAllowed",
    "type": "error"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "nativeToken",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "address",
    "name": "bridgedToken",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "uint256",
    "name": "amount",
    "type": "uint256"
    },
    {
    "indexed": false,
    "internalType": "address",
    "name": "recipient",
    "type": "address"
    }
    ],
    "name": "BridgingFinalized",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "sender",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "address",
    "name": "recipient",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "address",
    "name": "token",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "uint256",
    "name": "amount",
    "type": "uint256"
    }
    ],
    "name": "BridgingInitiated",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "nativeToken",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "address",
    "name": "customContract",
    "type": "address"
    }
    ],
    "name": "CustomContractSet",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address[]",
    "name": "tokens",
    "type": "address[]"
    }
    ],
    "name": "DeploymentConfirmed",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "uint8",
    "name": "version",
    "type": "uint8"
    }
    ],
    "name": "Initialized",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "NewToken",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "bridgedToken",
    "type": "address"
    }
    ],
    "name": "NewTokenDeployed",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "internalType": "address",
    "name": "previousOwner",
    "type": "address"
    },
    {
    "indexed": true,
    "internalType": "address",
    "name": "newOwner",
    "type": "address"
    }
    ],
    "name": "OwnershipTransferred",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "account",
    "type": "address"
    }
    ],
    "name": "Paused",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "remoteTokenBridge",
    "type": "address"
    }
    ],
    "name": "RemoteTokenBridgeSet",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "TokenDeployed",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "TokenReserved",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": false,
    "internalType": "address",
    "name": "account",
    "type": "address"
    }
    ],
    "name": "Unpaused",
    "type": "event"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_token",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "_amount",
    "type": "uint256"
    },
    {
    "internalType": "address",
    "name": "_recipient",
    "type": "address"
    }
    ],
    "name": "bridgeToken",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_token",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "_amount",
    "type": "uint256"
    },
    {
    "internalType": "address",
    "name": "_recipient",
    "type": "address"
    },
    {
    "internalType": "bytes",
    "name": "_permitData",
    "type": "bytes"
    }
    ],
    "name": "bridgeTokenWithPermit",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "name": "bridgedToNativeToken",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_nativeToken",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "_amount",
    "type": "uint256"
    },
    {
    "internalType": "address",
    "name": "_recipient",
    "type": "address"
    },
    {
    "internalType": "bytes",
    "name": "_tokenMetadata",
    "type": "bytes"
    }
    ],
    "name": "completeBridging",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address[]",
    "name": "_tokens",
    "type": "address[]"
    }
    ],
    "name": "confirmDeployment",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_securityCouncil",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "_messageService",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "_tokenBeacon",
    "type": "address"
    },
    {
    "internalType": "address[]",
    "name": "_reservedTokens",
    "type": "address[]"
    }
    ],
    "name": "initialize",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "messageService",
    "outputs": [
    {
    "internalType": "contract IMessageService",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "name": "nativeToBridgedToken",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "owner",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "pause",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "paused",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "remoteTokenBridge",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_token",
    "type": "address"
    }
    ],
    "name": "removeReserved",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "renounceOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_nativeToken",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "_targetContract",
    "type": "address"
    }
    ],
    "name": "setCustomContract",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address[]",
    "name": "_nativeTokens",
    "type": "address[]"
    }
    ],
    "name": "setDeployed",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_messageService",
    "type": "address"
    }
    ],
    "name": "setMessageService",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_remoteTokenBridge",
    "type": "address"
    }
    ],
    "name": "setRemoteTokenBridge",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "_token",
    "type": "address"
    }
    ],
    "name": "setReserved",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "tokenBeacon",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "newOwner",
    "type": "address"
    }
    ],
    "name": "transferOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "unpause",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    }
    ]
  • L2 (Linea)

    TokenBridge.abi
    [
    {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "AlreadyBridgedToken",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "bytes4",
    "name": "permitData",
    "type": "bytes4"
    },
    {
    "internalType": "bytes32",
    "name": "permitSelector",
    "type": "bytes32"
    }
    ],
    "name": "InvalidPermitData",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "sender",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "tokenBridge",
    "type": "address"
    }
    ],
    "name": "NotFromRemoteTokenBridge",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "sender",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "messageService",
    "type": "address"
    }
    ],
    "name": "NotMessagingService",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "token",
    "type": "address"
    }
    ],
    "name": "NotReserved",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "spender",
    "type": "address"
    }
    ],
    "name": "PermitNotAllowingBridge",
    "type": "error"
    },
    {
    "inputs": [
    {
    "internalType": "address",<