Canonical token bridge
The canonical token bridge is the pair of “lock & mint” contracts that allow bridging of any ERC-20 token. The bridge relies on the message service for cross-chain interactions.
The Linea team operates a UI for the official Linea bridge.
The canonical token bridge is optimized for technical partners who are deploying on Linea. We recommend that everyday users of Linea seeking to bridge their personal tokens between networks leverage one of the many bridges deployed to the network.
Linea seeks to foster a permissionless, resilient, decentralized environment — not to have our bridge be a centralized arbiter and point of failure.
To find out which bridges are currently operating on Linea, head to the ecosystem portal and click on the Bridge button to show all that are available.
Contracts
- Mainnet
- Linea Sepolia
- 
Ethereum Mainnet TokenBridge.abi[
 {
 "inputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "constructor"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBridgedToken",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBrigedToNativeTokenSet",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "CallerIsNotMessageService",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "bytes4",
 "name": "permitData",
 "type": "bytes4"
 },
 {
 "internalType": "bytes4",
 "name": "permitSelector",
 "type": "bytes4"
 }
 ],
 "name": "InvalidPermitData",
 "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": [
 
 ],
 "name": "SenderNotAuthorized",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "StatusAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNativeOnOtherLayer",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNotDeployed",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "ZeroAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "ZeroAmountNotAllowed",
 "type": "error"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 }
 ],
 "name": "BridgingFinalized",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "sender",
 "type": "address"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "BridgingInitiated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "customContract",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "CustomContractSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": false,
 "internalType": "address[]",
 "name": "tokens",
 "type": "address[]"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "confirmedBy",
 "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": true,
 "internalType": "address",
 "name": "newMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "oldMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "MessageServiceUpdated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "NewToken",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "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": "OwnershipTransferStarted",
 "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": true,
 "internalType": "address",
 "name": "remoteTokenBridge",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "RemoteTokenBridgeSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenDeployed",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "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": [
 
 ],
 "name": "acceptOwnership",
 "outputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "function"
 },
 {
 "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": "uint256",
 "name": "_chainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "_sourceChainId",
 "type": "uint256"
 },
 {
 "internalType": "uint256",
 "name": "_targetChainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "",
 "type": "uint256"
 },
 {
 "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": "pendingOwner",
 "outputs": [
 {
 "internalType": "address",
 "name": "",
 "type": "address"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "remoteSender",
 "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": "sourceChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "targetChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "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"
 }
 ]- Contracts:
 
- 
Linea Mainnet TokenBridge.abi[
 {
 "inputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "constructor"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBridgedToken",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBrigedToNativeTokenSet",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "CallerIsNotMessageService",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "bytes4",
 "name": "permitData",
 "type": "bytes4"
 },
 {
 "internalType": "bytes4",
 "name": "permitSelector",
 "type": "bytes4"
 }
 ],
 "name": "InvalidPermitData",
 "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": [
 
 ],
 "name": "SenderNotAuthorized",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "StatusAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNativeOnOtherLayer",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNotDeployed",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "ZeroAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "ZeroAmountNotAllowed",
 "type": "error"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 }
 ],
 "name": "BridgingFinalized",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "sender",
 "type": "address"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "BridgingInitiated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "customContract",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "CustomContractSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": false,
 "internalType": "address[]",
 "name": "tokens",
 "type": "address[]"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "confirmedBy",
 "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": true,
 "internalType": "address",
 "name": "newMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "oldMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "MessageServiceUpdated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "NewToken",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "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": "OwnershipTransferStarted",
 "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": true,
 "internalType": "address",
 "name": "remoteTokenBridge",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "RemoteTokenBridgeSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenDeployed",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "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": [
 
 ],
 "name": "acceptOwnership",
 "outputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "function"
 },
 {
 "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": "uint256",
 "name": "_chainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "_sourceChainId",
 "type": "uint256"
 },
 {
 "internalType": "uint256",
 "name": "_targetChainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "",
 "type": "uint256"
 },
 {
 "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": "pendingOwner",
 "outputs": [
 {
 "internalType": "address",
 "name": "",
 "type": "address"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "remoteSender",
 "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": "sourceChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "targetChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "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"
 }
 ]- Contracts:
 
- 
Ethereum Sepolia TokenBridge.abi[
 {
 "inputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "constructor"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBridgedToken",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBrigedToNativeTokenSet",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "CallerIsNotMessageService",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "bytes4",
 "name": "permitData",
 "type": "bytes4"
 },
 {
 "internalType": "bytes4",
 "name": "permitSelector",
 "type": "bytes4"
 }
 ],
 "name": "InvalidPermitData",
 "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": [
 
 ],
 "name": "SenderNotAuthorized",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "StatusAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNativeOnOtherLayer",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNotDeployed",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "ZeroAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "ZeroAmountNotAllowed",
 "type": "error"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 }
 ],
 "name": "BridgingFinalized",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "sender",
 "type": "address"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "BridgingInitiated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "customContract",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "CustomContractSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": false,
 "internalType": "address[]",
 "name": "tokens",
 "type": "address[]"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "confirmedBy",
 "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": true,
 "internalType": "address",
 "name": "newMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "oldMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "MessageServiceUpdated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "NewToken",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "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": "OwnershipTransferStarted",
 "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": true,
 "internalType": "address",
 "name": "remoteTokenBridge",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "RemoteTokenBridgeSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenDeployed",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "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": [
 
 ],
 "name": "acceptOwnership",
 "outputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "function"
 },
 {
 "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": "uint256",
 "name": "_chainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "_sourceChainId",
 "type": "uint256"
 },
 {
 "internalType": "uint256",
 "name": "_targetChainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "",
 "type": "uint256"
 },
 {
 "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": "pendingOwner",
 "outputs": [
 {
 "internalType": "address",
 "name": "",
 "type": "address"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "remoteSender",
 "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": "sourceChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "targetChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "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"
 }
 ]- Contracts:
 
- 
Linea Sepolia TokenBridge.abi[
 {
 "inputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "constructor"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBridgedToken",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "AlreadyBrigedToNativeTokenSet",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "CallerIsNotMessageService",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "bytes4",
 "name": "permitData",
 "type": "bytes4"
 },
 {
 "internalType": "bytes4",
 "name": "permitSelector",
 "type": "bytes4"
 }
 ],
 "name": "InvalidPermitData",
 "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": [
 
 ],
 "name": "SenderNotAuthorized",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "StatusAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNativeOnOtherLayer",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenNotDeployed",
 "type": "error"
 },
 {
 "inputs": [
 
 ],
 "name": "ZeroAddressNotAllowed",
 "type": "error"
 },
 {
 "inputs": [
 {
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "ZeroAmountNotAllowed",
 "type": "error"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 }
 ],
 "name": "BridgingFinalized",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "sender",
 "type": "address"
 },
 {
 "indexed": false,
 "internalType": "address",
 "name": "recipient",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "uint256",
 "name": "amount",
 "type": "uint256"
 }
 ],
 "name": "BridgingInitiated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "customContract",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "CustomContractSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": false,
 "internalType": "address[]",
 "name": "tokens",
 "type": "address[]"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "confirmedBy",
 "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": true,
 "internalType": "address",
 "name": "newMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "oldMessageService",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "MessageServiceUpdated",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "NewToken",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "bridgedToken",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "nativeToken",
 "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": "OwnershipTransferStarted",
 "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": true,
 "internalType": "address",
 "name": "remoteTokenBridge",
 "type": "address"
 },
 {
 "indexed": true,
 "internalType": "address",
 "name": "setBy",
 "type": "address"
 }
 ],
 "name": "RemoteTokenBridgeSet",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "internalType": "address",
 "name": "token",
 "type": "address"
 }
 ],
 "name": "TokenDeployed",
 "type": "event"
 },
 {
 "anonymous": false,
 "inputs": [
 {
 "indexed": true,
 "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": [
 
 ],
 "name": "acceptOwnership",
 "outputs": [
 
 ],
 "stateMutability": "nonpayable",
 "type": "function"
 },
 {
 "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": "uint256",
 "name": "_chainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "_sourceChainId",
 "type": "uint256"
 },
 {
 "internalType": "uint256",
 "name": "_targetChainId",
 "type": "uint256"
 },
 {
 "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": "uint256",
 "name": "",
 "type": "uint256"
 },
 {
 "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": "pendingOwner",
 "outputs": [
 {
 "internalType": "address",
 "name": "",
 "type": "address"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "remoteSender",
 "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": "sourceChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "type": "function"
 },
 {
 "inputs": [
 
 ],
 "name": "targetChainId",
 "outputs": [
 {
 "internalType": "uint256",
 "name": "",
 "type": "uint256"
 }
 ],
 "stateMutability": "view",
 "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"
 }
 ]- Contracts:
 
How to use
Workflow
- Triggering the transfer
- Without Permit
- User should first allow the bridge to transfer tokens on their behalf
- This is done by calling allowance()on the TokenBridge.
- Then, the user should call the bridgeToken()method.
 
- With Permit
- User can call bridgeTokenWithPermit()to pass permit data in a single transaction
 
- User can call 
- Triggering the delivery
- See the message service workflow.
Interface TokenBridge.sol
ITokenBridge.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;
interface ITokenBridge {
  event TokenReserved(address indexed token);
  event CustomContractSet(address indexed nativeToken, address indexed customContract, address indexed setBy);
  event BridgingInitiated(address indexed sender, address recipient, address indexed token, uint256 indexed amount);
  event BridgingFinalized(
    address indexed nativeToken,
    address indexed bridgedToken,
    uint256 indexed amount,
    address recipient
  );
  event NewToken(address indexed token);
  event NewTokenDeployed(address indexed bridgedToken, address indexed nativeToken);
  event RemoteTokenBridgeSet(address indexed remoteTokenBridge, address indexed setBy);
  event TokenDeployed(address indexed token);
  event DeploymentConfirmed(address[] tokens, address indexed confirmedBy);
  event MessageServiceUpdated(
    address indexed newMessageService,
    address indexed oldMessageService,
    address indexed setBy
  );
  error ReservedToken(address token);
  error RemoteTokenBridgeAlreadySet(address remoteTokenBridge);
  error AlreadyBridgedToken(address token);
  error InvalidPermitData(bytes4 permitData, bytes4 permitSelector);
  error PermitNotFromSender(address owner);
  error PermitNotAllowingBridge(address spender);
  error ZeroAmountNotAllowed(uint256 amount);
  error NotReserved(address token);
  error TokenNotDeployed(address token);
  error TokenNativeOnOtherLayer(address token);
  error AlreadyBrigedToNativeTokenSet(address token);
  error StatusAddressNotAllowed(address token);
  /**
   * @notice Similar to `bridgeToken` function but allows to pass additional
   *   permit data to do the ERC20 approval in a single transaction.
   * @param _token The address of the token to be bridged.
   * @param _amount The amount of the token to be bridged.
   * @param _recipient The address that will receive the tokens on the other chain.
   * @param _permitData The permit data for the token, if applicable.
   */
  function bridgeTokenWithPermit(
    address _token,
    uint256 _amount,
    address _recipient,
    bytes calldata _permitData
  ) external payable;
  /**
   * @dev It can only be called from the Message Service. To finalize the bridging
   *   process, a user or postmen needs to use the `claimMessage` function of the
   *   Message Service to trigger the transaction.
   * @param _nativeToken The address of the token on its native chain.
   * @param _amount The amount of the token to be received.
   * @param _recipient The address that will receive the tokens.
   * @param _chainId The source chainId or target chaindId for this token
   * @param _tokenMetadata Additional data used to deploy the bridged token if it
   *   doesn't exist already.
   */
  function completeBridging(
    address _nativeToken,
    uint256 _amount,
    address _recipient,
    uint256 _chainId,
    bytes calldata _tokenMetadata
  ) external;
  /**
   * @dev Change the address of the Message Service.
   * @param _messageService The address of the new Message Service.
   */
  function setMessageService(address _messageService) external;
  /**
   * @dev It can only be called from the Message Service. To change the status of
   *   the native tokens to DEPLOYED meaning they have been deployed on the other chain
   *   a user or postman needs to use the `claimMessage` function of the
   *   Message Service to trigger the transaction.
   * @param _nativeTokens The addresses of the native tokens.
   */
  function setDeployed(address[] memory _nativeTokens) external;
  /**
   * @dev Sets the address of the remote token bridge. Can only be called once.
   * @param _remoteTokenBridge The address of the remote token bridge to be set.
   */
  function setRemoteTokenBridge(address _remoteTokenBridge) external;
  /**
   * @dev Removes a token from the reserved list.
   * @param _token The address of the token to be removed from the reserved list.
   */
  function removeReserved(address _token) external;
  /**
   * @dev Linea can set a custom ERC20 contract for specific ERC20.
   *   For security purpose, Linea can only call this function if the token has
   *   not been bridged yet.
   * @param _nativeToken address of the token on the source chain.
   * @param _targetContract address of the custom contract.
   */
  function setCustomContract(address _nativeToken, address _targetContract) external;
  /**
   * @dev Pause the contract, can only be called by the owner.
   */
  function pause() external;
  /**
   * @dev Unpause the contract, can only be called by the owner.
   */
  function unpause() external;
}