Skip to main content

Canonical Token Bridge

The Canonical Token Bridge is the “lock & mint” contracts that allow bridging to any ERC20, which relies on the Message Service for cross-chain interactions and does not come with any UI.

Contracts

  • 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",
    "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"
    }
    ]

How to use

Workflow

  1. Triggering the transfer
  • Without Permit
    • User should first allow the bridge to transfer tokens on his 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
  1. Triggering the delivery

Interface TokenBridge.sol

TokenBridge.sol
pragma solidity ^0.8.19;

interface TokenBridge {

event TokenReserved(address token);
event CustomContractSet(address nativeToken, address customContract);
event BridgingInitiated(address sender, address recipient, address token, uint256 amount);
event BridgingFinalized(address nativeToken, address bridgedToken, uint256 amount, address recipient);
event NewToken(address token);
event NewTokenDeployed(address bridgedToken);

error NotMessagingService(address sender, address messageService);
error NotFromRemoteTokenBridge(address sender, address tokenBridge);
error ReservedToken(address token);
error RemoteTokenBridgeAlreadySet(address remoteTokenBridge);
error AlreadyBridgedToken(address token);
error InvalidPermitData(bytes4 permitData, bytes32 permitSelector);
error PermitNotFromSender(address owner);
error PermitNotAllowingBridge(address spender);
error ZeroAddressNotAllowed(address addr);
error ZeroAmountNotAllowed(uint256 amount);

/**
@dev User should first allow the bridge to transfer tokens on his behalf. Alternatively, you can pass permit data to do so in a single transaction.
If you want the transfer to be automatically executed on the destination chain. You should send enough ETH to pay the postmen fees.
Note that Linea can reserved some tokens (which use a dedicated bridge). In this case, the token cannot be bridged. Linea can only reserved tokens that are not been bridged yet.
Linea can pause the bridge for security reason. In this case new bridge transaction would revert.

@notice This function is the single entry point to bridge tokens to the other chain, both for native and already bridged tokens.
You can use it to bridge any ERC20. If the token is bridged for the first time an ERC20 (BridgedToken.sol) will be automatically deployed on the target chain.

@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 bridged tokens on the other blockchain.
*/
function bridgeToken(
address token,
uint256 amount,
address recipient
) public payable;

function bridgeTokenWithPermit(
address token,
uint256 amount,
address recipient,
bytes calldata permitData
) external payable;
}