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 this bridge, available at https://bridge.linea.build/.
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;
}