EndpointV2
0x6f475642a6e85809b1c36fa62763669b1b48dd5b
Verification
Verified
v0.8.22+commit.4fc1097e
Type
Contract
24,005 bytes
ABI entries
103
31 read · 24 write
License
none
Contract information
- Address
- 0x6f475642a6e85809b1c36fa62763669b1b48dd5b
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.22+commit.4fc1097e
- Optimization
- Enabled
- Creator
- 0x9F403140Bc…1Bbd4eF327
- Creation tx
- 0x747e1d6ce7…cef878043b
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (31)
EMPTY_PAYLOAD_HASH() → bytes32
NIL_PAYLOAD_HASH() → bytes32
blockedLibrary() → address
composeQueue(address, address, bytes32, uint16) → bytes32
defaultReceiveLibrary(uint32) → address
defaultReceiveLibraryTimeout(uint32) → address, uint256
defaultSendLibrary(uint32) → address
delegates(address) → address
eid() → uint32
getConfig(address, address, uint32, uint32) → bytes
getReceiveLibrary(address, uint32) → address, bool
getRegisteredLibraries() → address[]
getSendContext() → uint32, address
getSendLibrary(address, uint32) → address
inboundNonce(address, uint32, bytes32) → uint64
inboundPayloadHash(address, uint32, bytes32, uint64) → bytes32
initializable(tuple, address) → bool
isDefaultSendLibrary(address, uint32) → bool
isRegisteredLibrary(address) → bool
isSendingMessage() → bool
isSupportedEid(uint32) → bool
isValidReceiveLibrary(address, uint32, address) → bool
lazyInboundNonce(address, uint32, bytes32) → uint64
lzToken() → address
nativeToken() → address
nextGuid(address, uint32, bytes32) → bytes32
outboundNonce(address, uint32, bytes32) → uint64
owner() → address
quote(tuple, address) → tuple
receiveLibraryTimeout(address, uint32) → address, uint256
verifiable(tuple, address) → bool
Events (20)
ComposeDeliveredComposeSentDefaultReceiveLibrarySetDefaultReceiveLibraryTimeoutSetDefaultSendLibrarySetDelegateSetInboundNonceSkippedLibraryRegisteredLzComposeAlertLzReceiveAlertLzTokenSetOwnershipTransferredPacketBurntPacketDeliveredPacketNilifiedPacketSentPacketVerifiedReceiveLibrarySetReceiveLibraryTimeoutSetSendLibrarySet
ABI
[
{
"inputs": [
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "LZ_AlreadyRegistered",
"type": "error"
},
{
"inputs": [],
"name": "LZ_ComposeExists",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "expected",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "actual",
"type": "bytes32"
}
],
"name": "LZ_ComposeNotFound",
"type": "error"
},
{
"inputs": [],
"name": "LZ_DefaultReceiveLibUnavailable",
"type": "error"
},
{
"inputs": [],
"name": "LZ_DefaultSendLibUnavailable",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "requiredNative",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "suppliedNative",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requiredLzToken",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "suppliedLzToken",
"type": "uint256"
}
],
"name": "LZ_InsufficientFee",
"type": "error"
},
{
"inputs": [],
"name": "LZ_InvalidExpiry",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"name": "LZ_InvalidNonce",
"type": "error"
},
{
"inputs": [],
"name": "LZ_InvalidPayloadHash",
"type": "error"
},
{
"inputs": [],
"name": "LZ_InvalidReceiveLibrary",
"type": "error"
},
{
"inputs": [],
"name": "LZ_LzTokenUnavailable",
"type": "error"
},
{
"inputs": [],
"name": "LZ_OnlyNonDefaultLib",
"type": "error"
},
{
"inputs": [],
"name": "LZ_OnlyReceiveLib",
"type": "error"
},
{
"inputs": [],
"name": "LZ_OnlyRegisteredLib",
"type": "error"
},
{
"inputs": [],
"name": "LZ_OnlyRegisteredOrDefaultLib",
"type": "error"
},
{
"inputs": [],
"name": "LZ_OnlySendLib",
"type": "error"
},
{
"inputs": [],
"name": "LZ_PathNotInitializable",
"type": "error"
},
{
"inputs": [],
"name": "LZ_PathNotVerifiable",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "expected",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "actual",
"type": "bytes32"
}
],
"name": "LZ_PayloadHashNotFound",
"type": "error"
},
{
"inputs": [],
"name": "LZ_SameValue",
"type": "error"
},
{
"inputs": [],
"name": "LZ_SendReentrancy",
"type": "error"
},
{
"inputs": [],
"name": "LZ_Unauthorized",
"type": "error"
},
{
"inputs": [],
"name": "LZ_UnsupportedEid",
"type": "error"
},
{
"inputs": [],
"name": "LZ_UnsupportedInterface",
"type": "error"
},
{
"inputs": [],
"name": "LZ_ZeroLzTokenFee",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
}
],
"name": "Transfer_NativeFailed",
"type": "error"
},
{
"inputs": [],
"name": "Transfer_ToAddressIsZero",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "guid",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint16",
"name": "index",
"type": "uint16"
}
],
"name": "ComposeDelivered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "guid",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint16",
"name": "index",
"type": "uint16"
},
{
"indexed": false,
"internalType": "bytes",
"name": "message",
"type": "bytes"
}
],
"name": "ComposeSent",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "address",
"name": "newLib",
"type": "address"
}
],
"name": "DefaultReceiveLibrarySet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "address",
"name": "oldLib",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "expiry",
"type": "uint256"
}
],
"name": "DefaultReceiveLibraryTimeoutSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "address",
"name": "newLib",
"type": "address"
}
],
"name": "DefaultSendLibrarySet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "delegate",
"type": "address"
}
],
"name": "DelegateSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"name": "InboundNonceSkipped",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "newLib",
"type": "address"
}
],
"name": "LibraryRegistered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "executor",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "guid",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint16",
"name": "index",
"type": "uint16"
},
{
"indexed": false,
"internalType": "uint256",
"name": "gas",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "message",
"type": "bytes"
},
{
"indexed": false,
"internalType": "bytes",
"name": "extraData",
"type": "bytes"
},
{
"indexed": false,
"internalType": "bytes",
"name": "reason",
"type": "bytes"
}
],
"name": "LzComposeAlert",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "executor",
"type": "address"
},
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"indexed": false,
"internalType": "struct Origin",
"name": "origin",
"type": "tuple"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "guid",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "gas",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "message",
"type": "bytes"
},
{
"indexed": false,
"internalType": "bytes",
"name": "extraData",
"type": "bytes"
},
{
"indexed": false,
"internalType": "bytes",
"name": "reason",
"type": "bytes"
}
],
"name": "LzReceiveAlert",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "LzTokenSet",
"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": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "payloadHash",
"type": "bytes32"
}
],
"name": "PacketBurnt",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"indexed": false,
"internalType": "struct Origin",
"name": "origin",
"type": "tuple"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "PacketDelivered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "payloadHash",
"type": "bytes32"
}
],
"name": "PacketNilified",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "encodedPayload",
"type": "bytes"
},
{
"indexed": false,
"internalType": "bytes",
"name": "options",
"type": "bytes"
},
{
"indexed": false,
"internalType": "address",
"name": "sendLibrary",
"type": "address"
}
],
"name": "PacketSent",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"indexed": false,
"internalType": "struct Origin",
"name": "origin",
"type": "tuple"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "payloadHash",
"type": "bytes32"
}
],
"name": "PacketVerified",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "address",
"name": "newLib",
"type": "address"
}
],
"name": "ReceiveLibrarySet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "address",
"name": "oldLib",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timeout",
"type": "uint256"
}
],
"name": "ReceiveLibraryTimeoutSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"indexed": false,
"internalType": "address",
"name": "newLib",
"type": "address"
}
],
"name": "SendLibrarySet",
"type": "event"
},
{
"inputs": [],
"name": "EMPTY_PAYLOAD_HASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NIL_PAYLOAD_HASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "blockedLibrary",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "uint32",
"name": "_srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "_sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "_nonce",
"type": "uint64"
},
{
"internalType": "bytes32",
"name": "_payloadHash",
"type": "bytes32"
}
],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"internalType": "struct Origin",
"name": "_origin",
"type": "tuple"
},
{
"internalType": "bytes32",
"name": "_guid",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "_message",
"type": "bytes"
}
],
"name": "clear",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "bytes32",
"name": "guid",
"type": "bytes32"
},
{
"internalType": "uint16",
"name": "index",
"type": "uint16"
}
],
"name": "composeQueue",
"outputs": [
{
"internalType": "bytes32",
"name": "messageHash",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
}
],
"name": "defaultReceiveLibrary",
"outputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
}
],
"name": "defaultReceiveLibraryTimeout",
"outputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
},
{
"internalType": "uint256",
"name": "expiry",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "dstEid",
"type": "uint32"
}
],
"name": "defaultSendLibrary",
"outputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "oapp",
"type": "address"
}
],
"name": "delegates",
"outputs": [
{
"internalType": "address",
"name": "delegate",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "eid",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "address",
"name": "_lib",
"type": "address"
},
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "uint32",
"name": "_configType",
"type": "uint32"
}
],
"name": "getConfig",
"outputs": [
{
"internalType": "bytes",
"name": "config",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_receiver",
"type": "address"
},
{
"internalType": "uint32",
"name": "_srcEid",
"type": "uint32"
}
],
"name": "getReceiveLibrary",
"outputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
},
{
"internalType": "bool",
"name": "isDefault",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getRegisteredLibraries",
"outputs": [
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getSendContext",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_sender",
"type": "address"
},
{
"internalType": "uint32",
"name": "_dstEid",
"type": "uint32"
}
],
"name": "getSendLibrary",
"outputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_receiver",
"type": "address"
},
{
"internalType": "uint32",
"name": "_srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "_sender",
"type": "bytes32"
}
],
"name": "inboundNonce",
"outputs": [
{
"internalType": "uint64",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "inboundNonce",
"type": "uint64"
}
],
"name": "inboundPayloadHash",
"outputs": [
{
"internalType": "bytes32",
"name": "payloadHash",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"internalType": "struct Origin",
"name": "_origin",
"type": "tuple"
},
{
"internalType": "address",
"name": "_receiver",
"type": "address"
}
],
"name": "initializable",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_sender",
"type": "address"
},
{
"internalType": "uint32",
"name": "_dstEid",
"type": "uint32"
}
],
"name": "isDefaultSendLibrary",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
}
],
"name": "isRegisteredLibrary",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isSendingMessage",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
}
],
"name": "isSupportedEid",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_receiver",
"type": "address"
},
{
"internalType": "uint32",
"name": "_srcEid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_actualReceiveLib",
"type": "address"
}
],
"name": "isValidReceiveLibrary",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
}
],
"name": "lazyInboundNonce",
"outputs": [
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_guid",
"type": "bytes32"
},
{
"internalType": "uint16",
"name": "_index",
"type": "uint16"
},
{
"internalType": "bytes",
"name": "_message",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "_extraData",
"type": "bytes"
}
],
"name": "lzCompose",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_guid",
"type": "bytes32"
},
{
"internalType": "uint16",
"name": "_index",
"type": "uint16"
},
{
"internalType": "uint256",
"name": "_gas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_message",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "_extraData",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "_reason",
"type": "bytes"
}
],
"name": "lzComposeAlert",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"internalType": "struct Origin",
"name": "_origin",
"type": "tuple"
},
{
"internalType": "address",
"name": "_receiver",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_guid",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "_message",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "_extraData",
"type": "bytes"
}
],
"name": "lzReceive",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"internalType": "struct Origin",
"name": "_origin",
"type": "tuple"
},
{
"internalType": "address",
"name": "_receiver",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_guid",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "_gas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_message",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "_extraData",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "_reason",
"type": "bytes"
}
],
"name": "lzReceiveAlert",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "lzToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "nativeToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_sender",
"type": "address"
},
{
"internalType": "uint32",
"name": "_dstEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "_receiver",
"type": "bytes32"
}
],
"name": "nextGuid",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "uint32",
"name": "_srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "_sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "_nonce",
"type": "uint64"
},
{
"internalType": "bytes32",
"name": "_payloadHash",
"type": "bytes32"
}
],
"name": "nilify",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint32",
"name": "dstEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "receiver",
"type": "bytes32"
}
],
"name": "outboundNonce",
"outputs": [
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "dstEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "receiver",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "message",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "options",
"type": "bytes"
},
{
"internalType": "bool",
"name": "payInLzToken",
"type": "bool"
}
],
"internalType": "struct MessagingParams",
"name": "_params",
"type": "tuple"
},
{
"internalType": "address",
"name": "_sender",
"type": "address"
}
],
"name": "quote",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "nativeFee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lzTokenFee",
"type": "uint256"
}
],
"internalType": "struct MessagingFee",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
}
],
"name": "receiveLibraryTimeout",
"outputs": [
{
"internalType": "address",
"name": "lib",
"type": "address"
},
{
"internalType": "uint256",
"name": "expiry",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_token",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "recoverToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_lib",
"type": "address"
}
],
"name": "registerLibrary",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "dstEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "receiver",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "message",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "options",
"type": "bytes"
},
{
"internalType": "bool",
"name": "payInLzToken",
"type": "bool"
}
],
"internalType": "struct MessagingParams",
"name": "_params",
"type": "tuple"
},
{
"internalType": "address",
"name": "_refundAddress",
"type": "address"
}
],
"name": "send",
"outputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "guid",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
},
{
"components": [
{
"internalType": "uint256",
"name": "nativeFee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lzTokenFee",
"type": "uint256"
}
],
"internalType": "struct MessagingFee",
"name": "fee",
"type": "tuple"
}
],
"internalType": "struct MessagingReceipt",
"name": "",
"type": "tuple"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_guid",
"type": "bytes32"
},
{
"internalType": "uint16",
"name": "_index",
"type": "uint16"
},
{
"internalType": "bytes",
"name": "_message",
"type": "bytes"
}
],
"name": "sendCompose",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "address",
"name": "_lib",
"type": "address"
},
{
"components": [
{
"internalType": "uint32",
"name": "eid",
"type": "uint32"
},
{
"internalType": "uint32",
"name": "configType",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "config",
"type": "bytes"
}
],
"internalType": "struct SetConfigParam[]",
"name": "_params",
"type": "tuple[]"
}
],
"name": "setConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_newLib",
"type": "address"
},
{
"internalType": "uint256",
"name": "_gracePeriod",
"type": "uint256"
}
],
"name": "setDefaultReceiveLibrary",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_lib",
"type": "address"
},
{
"internalType": "uint256",
"name": "_expiry",
"type": "uint256"
}
],
"name": "setDefaultReceiveLibraryTimeout",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_newLib",
"type": "address"
}
],
"name": "setDefaultSendLibrary",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_delegate",
"type": "address"
}
],
"name": "setDelegate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_lzToken",
"type": "address"
}
],
"name": "setLzToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_newLib",
"type": "address"
},
{
"internalType": "uint256",
"name": "_gracePeriod",
"type": "uint256"
}
],
"name": "setReceiveLibrary",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_lib",
"type": "address"
},
{
"internalType": "uint256",
"name": "_expiry",
"type": "uint256"
}
],
"name": "setReceiveLibraryTimeout",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "uint32",
"name": "_eid",
"type": "uint32"
},
{
"internalType": "address",
"name": "_newLib",
"type": "address"
}
],
"name": "setSendLibrary",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_oapp",
"type": "address"
},
{
"internalType": "uint32",
"name": "_srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "_sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "_nonce",
"type": "uint64"
}
],
"name": "skip",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"internalType": "struct Origin",
"name": "_origin",
"type": "tuple"
},
{
"internalType": "address",
"name": "_receiver",
"type": "address"
}
],
"name": "verifiable",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint32",
"name": "srcEid",
"type": "uint32"
},
{
"internalType": "bytes32",
"name": "sender",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "nonce",
"type": "uint64"
}
],
"internalType": "struct Origin",
"name": "_origin",
"type": "tuple"
},
{
"internalType": "address",
"name": "_receiver",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_payloadHash",
"type": "bytes32"
}
],
"name": "verify",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: LZBL-1.2
pragma solidity ^0.8.20;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { MessagingFee, MessagingParams, MessagingReceipt, Origin, ILayerZeroEndpointV2 } from "./interfaces/ILayerZeroEndpointV2.sol";
import { ISendLib, Packet } from "./interfaces/ISendLib.sol";
import { ILayerZeroReceiver } from "./interfaces/ILayerZeroReceiver.sol";
import { Errors } from "./libs/Errors.sol";
import { GUID } from "./libs/GUID.sol";
import { Transfer } from "./libs/Transfer.sol";
import { MessagingChannel } from "./MessagingChannel.sol";
import { MessagingComposer } from "./MessagingComposer.sol";
import { MessageLibManager } from "./MessageLibManager.sol";
import { MessagingContext } from "./MessagingContext.sol";
// LayerZero EndpointV2 is fully backward compatible with LayerZero Endpoint(V1), but it also supports additional
// features that Endpoint(V1) does not support now and may not in the future. We have also changed some terminology
// to clarify pre-existing language that might have been confusing.
//
// The following is a list of terminology changes:
// -chainId -> eid
// - Rationale: chainId was a term we initially used to describe an endpoint on a specific chain. Since
// LayerZero supports non-EVMs we could not map the classic EVM chainIds to the LayerZero chainIds, making it
// confusing for developers. With the addition of EndpointV2 and its backward compatible nature, we would have
// two chainIds per chain that has Endpoint(V1), further confusing developers. We have decided to change the
// name to Endpoint Id, or eid, for simplicity and clarity.
// -adapterParams -> options
// -userApplication -> oapp. Omnichain Application
// -srcAddress -> sender
// -dstAddress -> receiver
// - Rationale: The sender/receiver on EVM is the address. However, on non-EVM chains, the sender/receiver could
// represented as a public key, or some other identifier. The term sender/receiver is more generic
// -payload -> message.
// - Rationale: The term payload is used in the context of a packet, which is a combination of the message and GUID
contract EndpointV2 is ILayerZeroEndpointV2, MessagingChannel, MessageLibManager, MessagingComposer, MessagingContext {
address public lzToken;
mapping(address oapp => address delegate) public delegates;
/// @param _eid the unique Endpoint Id for this deploy that all other Endpoints can use to send to it
constructor(uint32 _eid, address _owner) MessagingChannel(_eid) {
_transferOwnership(_owner);
}
/// @dev MESSAGING STEP 0
/// @notice This view function gives the application built on top of LayerZero the ability to requests a quote
/// with the same parameters as they would to send their message. Since the quotes are given on chain there is a
/// race condition in which the prices could change between the time the user gets their quote and the time they
/// submit their message. If the price moves up and the user doesn't send enough funds the transaction will revert,
/// if the price goes down the _refundAddress provided by the app will be refunded the difference.
/// @param _params the messaging parameters
/// @param _sender the sender of the message
function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory) {
// lzToken must be set to support payInLzToken
if (_params.payInLzToken && lzToken == address(0x0)) revert Errors.LZ_LzTokenUnavailable();
// get the correct outbound nonce
uint64 nonce = outboundNonce[_sender][_params.dstEid][_params.receiver] + 1;
// construct the packet with a GUID
Packet memory packet = Packet({
nonce: nonce,
srcEid: eid,
sender: _sender,
dstEid: _params.dstEid,
receiver: _params.receiver,
guid: GUID.generate(nonce, eid, _sender, _params.dstEid, _params.receiver),
message: _params.message
});
// get the send library by sender and dst eid
// use _ to avoid variable shadowing
address _sendLibrary = getSendLibrary(_sender, _params.dstEid);
return ISendLib(_sendLibrary).quote(packet, _params.options, _params.payInLzToken);
}
/// @dev MESSAGING STEP 1 - OApp need to transfer the fees to the endpoint before sending the message
/// @param _params the messaging parameters
/// @param _refundAddress the address to refund both the native and lzToken
function send(
MessagingParams calldata _params,
address _refundAddress
) external payable sendContext(_params.dstEid, msg.sender) returns (MessagingReceipt memory) {
if (_params.payInLzToken && lzToken == address(0x0)) revert Errors.LZ_LzTokenUnavailable();
// send message
(MessagingReceipt memory receipt, address _sendLibrary) = _send(msg.sender, _params);
// OApp can simulate with 0 native value it will fail with error including the required fee, which can be provided in the actual call
// this trick can be used to avoid the need to write the quote() function
// however, without the quote view function it will be hard to compose an oapp on chain
uint256 suppliedNative = _suppliedNative();
uint256 suppliedLzToken = _suppliedLzToken(_params.payInLzToken);
_assertMessagingFee(receipt.fee, suppliedNative, suppliedLzToken);
// handle lz token fees
_payToken(lzToken, receipt.fee.lzTokenFee, suppliedLzToken, _sendLibrary, _refundAddress);
// handle native fees
_payNative(receipt.fee.nativeFee, suppliedNative, _sendLibrary, _refundAddress);
return receipt;
}
/// @dev internal function for sending the messages used by all external send methods
/// @param _sender the address of the application sending the message to the destination chain
/// @param _params the messaging parameters
function _send(
address _sender,
MessagingParams calldata _params
) internal returns (MessagingReceipt memory, address) {
// get the correct outbound nonce
uint64 latestNonce = _outbound(_sender, _params.dstEid, _params.receiver);
// construct the packet with a GUID
Packet memory packet = Packet({
nonce: latestNonce,
srcEid: eid,
sender: _sender,
dstEid: _params.dstEid,
receiver: _params.receiver,
guid: GUID.generate(latestNonce, eid, _sender, _params.dstEid, _params.receiver),
message: _params.message
});
// get the send library by sender and dst eid
address _sendLibrary = getSendLibrary(_sender, _params.dstEid);
// messageLib always returns encodedPacket with guid
(MessagingFee memory fee, bytes memory encodedPacket) = ISendLib(_sendLibrary).send(
packet,
_params.options,
_params.payInLzToken
);
// Emit packet information for DVNs, Executors, and any other offchain infrastructure to only listen
// for this one event to perform their actions.
emit PacketSent(encodedPacket, _params.options, _sendLibrary);
return (MessagingReceipt(packet.guid, latestNonce, fee), _sendLibrary);
}
/// @dev MESSAGING STEP 2 - on the destination chain
/// @dev configured receive library verifies a message
/// @param _origin a struct holding the srcEid, nonce, and sender of the message
/// @param _receiver the receiver of the message
/// @param _payloadHash the payload hash of the message
function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external {
if (!isValidReceiveLibrary(_receiver, _origin.srcEid, msg.sender)) revert Errors.LZ_InvalidReceiveLibrary();
uint64 lazyNonce = lazyInboundNonce[_receiver][_origin.srcEid][_origin.sender];
if (!_initializable(_origin, _receiver, lazyNonce)) revert Errors.LZ_PathNotInitializable();
if (!_verifiable(_origin, _receiver, lazyNonce)) revert Errors.LZ_PathNotVerifiable();
// insert the message into the message channel
_inbound(_receiver, _origin.srcEid, _origin.sender, _origin.nonce, _payloadHash);
emit PacketVerified(_origin, _receiver, _payloadHash);
}
/// @dev MESSAGING STEP 3 - the last step
/// @dev execute a verified message to the designated receiver
/// @dev the execution provides the execution context (caller, extraData) to the receiver. the receiver can optionally assert the caller and validate the untrusted extraData
/// @dev cant reentrant because the payload is cleared before execution
/// @param _origin the origin of the message
/// @param _receiver the receiver of the message
/// @param _guid the guid of the message
/// @param _message the message
/// @param _extraData the extra data provided by the executor. this data is untrusted and should be validated.
function lzReceive(
Origin calldata _origin,
address _receiver,
bytes32 _guid,
bytes calldata _message,
bytes calldata _extraData
) external payable {
// clear the payload first to prevent reentrancy, and then execute the message
_clearPayload(_receiver, _origin.srcEid, _origin.sender, _origin.nonce, abi.encodePacked(_guid, _message));
ILayerZeroReceiver(_receiver).lzReceive{ value: msg.value }(_origin, _guid, _message, msg.sender, _extraData);
emit PacketDelivered(_origin, _receiver);
}
/// @param _origin the origin of the message
/// @param _receiver the receiver of the message
/// @param _guid the guid of the message
/// @param _message the message
/// @param _extraData the extra data provided by the executor.
/// @param _reason the reason for failure
function lzReceiveAlert(
Origin calldata _origin,
address _receiver,
bytes32 _guid,
uint256 _gas,
uint256 _value,
bytes calldata _message,
bytes calldata _extraData,
bytes calldata _reason
) external {
emit LzReceiveAlert(_receiver, msg.sender, _origin, _guid, _gas, _value, _message, _extraData, _reason);
}
/// @dev Oapp uses this interface to clear a message.
/// @dev this is a PULL mode versus the PUSH mode of lzReceive
/// @dev the cleared message can be ignored by the app (effectively burnt)
/// @dev authenticated by oapp
/// @param _origin the origin of the message
/// @param _guid the guid of the message
/// @param _message the message
function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external {
_assertAuthorized(_oapp);
bytes memory payload = abi.encodePacked(_guid, _message);
_clearPayload(_oapp, _origin.srcEid, _origin.sender, _origin.nonce, payload);
emit PacketDelivered(_origin, _oapp);
}
/// @dev allows reconfiguration to recover from wrong configurations
/// @dev users should never approve the EndpointV2 contract to spend their non-layerzero tokens
/// @dev override this function if the endpoint is charging ERC20 tokens as native
/// @dev only owner
/// @param _lzToken the new layer zero token address
function setLzToken(address _lzToken) public virtual onlyOwner {
lzToken = _lzToken;
emit LzTokenSet(_lzToken);
}
/// @dev recover the token sent to this contract by mistake
/// @dev only owner
/// @param _token the token to recover. if 0x0 then it is native token
/// @param _to the address to send the token to
/// @param _amount the amount to send
function recoverToken(address _token, address _to, uint256 _amount) external onlyOwner {
Transfer.nativeOrToken(_token, _to, _amount);
}
/// @dev handling token payments on endpoint. the sender must approve the endpoint to spend the token
/// @dev internal function
/// @param _token the token to pay
/// @param _required the amount required
/// @param _supplied the amount supplied
/// @param _receiver the receiver of the token
function _payToken(
address _token,
uint256 _required,
uint256 _supplied,
address _receiver,
address _refundAddress
) internal {
if (_required > 0) {
Transfer.token(_token, _receiver, _required);
}
if (_required < _supplied) {
unchecked {
// refund the excess
Transfer.token(_token, _refundAddress, _supplied - _required);
}
}
}
/// @dev handling native token payments on endpoint
/// @dev override this if the endpoint is charging ERC20 tokens as native
/// @dev internal function
/// @param _required the amount required
/// @param _supplied the amount supplied
/// @param _receiver the receiver of the native token
/// @param _refundAddress the address to refund the excess to
function _payNative(
uint256 _required,
uint256 _supplied,
address _receiver,
address _refundAddress
) internal virtual {
if (_required > 0) {
Transfer.native(_receiver, _required);
}
if (_required < _supplied) {
unchecked {
// refund the excess
Transfer.native(_refundAddress, _supplied - _required);
}
}
}
/// @dev get the balance of the lzToken as the supplied lzToken fee if payInLzToken is true
function _suppliedLzToken(bool _payInLzToken) internal view returns (uint256 supplied) {
if (_payInLzToken) {
supplied = IERC20(lzToken).balanceOf(address(this));
// if payInLzToken is true, the supplied fee must be greater than 0 to prevent a race condition
// in which an oapp sending a message with lz token and the lz token is set to a new token between the tx
// being sent and the tx being mined. if the required lz token fee is 0 and the old lz token would be
// locked in the contract instead of being refunded
if (supplied == 0) revert Errors.LZ_ZeroLzTokenFee();
}
}
/// @dev override this if the endpoint is charging ERC20 tokens as native
function _suppliedNative() internal view virtual returns (uint256) {
return msg.value;
}
/// @dev Assert the required fees and the supplied fees are enough
function _assertMessagingFee(
MessagingFee memory _required,
uint256 _suppliedNativeFee,
uint256 _suppliedLzTokenFee
) internal pure {
if (_required.nativeFee > _suppliedNativeFee || _required.lzTokenFee > _suppliedLzTokenFee) {
revert Errors.LZ_InsufficientFee(
_required.nativeFee,
_suppliedNativeFee,
_required.lzTokenFee,
_suppliedLzTokenFee
);
}
}
/// @dev override this if the endpoint is charging ERC20 tokens as native
/// @return 0x0 if using native. otherwise the address of the native ERC20 token
function nativeToken() external view virtual returns (address) {
return address(0x0);
}
/// @notice delegate is authorized by the oapp to configure anything in layerzero
function setDelegate(address _delegate) external {
delegates[msg.sender] = _delegate;
emit DelegateSet(msg.sender, _delegate);
}
// ========================= Internal =========================
function _initializable(
Origin calldata _origin,
address _receiver,
uint64 _lazyInboundNonce
) internal view returns (bool) {
return
_lazyInboundNonce > 0 || // allowInitializePath already checked
ILayerZeroReceiver(_receiver).allowInitializePath(_origin);
}
/// @dev bytes(0) payloadHash can never be submitted
function _verifiable(
Origin calldata _origin,
address _receiver,
uint64 _lazyInboundNonce
) internal view returns (bool) {
return
_origin.nonce > _lazyInboundNonce || // either initializing an empty slot or reverifying
inboundPayloadHash[_receiver][_origin.srcEid][_origin.sender][_origin.nonce] != EMPTY_PAYLOAD_HASH; // only allow reverifying if it hasn't been executed
}
/// @dev assert the caller to either be the oapp or the delegate
function _assertAuthorized(address _oapp) internal view override(MessagingChannel, MessageLibManager) {
if (msg.sender != _oapp && msg.sender != delegates[_oapp]) revert Errors.LZ_Unauthorized();
}
// ========================= VIEW FUNCTIONS FOR OFFCHAIN ONLY =========================
// Not involved in any state transition function.
// ====================================================================================
function initializable(Origin calldata _origin, address _receiver) external view returns (bool) {
return _initializable(_origin, _receiver, lazyInboundNonce[_receiver][_origin.srcEid][_origin.sender]);
}
function verifiable(Origin calldata _origin, address _receiver) external view returns (bool) {
return _verifiable(_origin, _receiver, lazyInboundNonce[_receiver][_origin.srcEid][_origin.sender]);
}
}
Chain explorer3736msChain node97ms