@layerzerolabs/lz-evm-oapp-v1 1.5.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/libraries/LzLib.sol +86 -0
- package/contracts/lzApp/LzApp.sol +165 -0
- package/contracts/lzApp/NonblockingLzApp.sol +87 -0
- package/contracts/mocks/LZEndpointMock.sol +442 -0
- package/contracts/util/BytesLib.sol +490 -0
- package/contracts/util/ExcessivelySafeCall.sol +133 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/index.d.ts +3 -0
- package/dist/typechain-types/@layerzerolabs/index.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/index.js +3 -0
- package/dist/typechain-types/@layerzerolabs/index.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/index.d.ts +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/index.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/index.js +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/index.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.d.ts +295 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.js +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.d.ts +56 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.js +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.d.ts +104 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.js +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.d.ts +4 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.js +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.js.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/index.d.ts +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/index.d.ts.map +1 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/index.js +3 -0
- package/dist/typechain-types/@layerzerolabs/lz-evm-v1-0.7/index.js.map +1 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/Ownable.d.ts +90 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/Ownable.d.ts.map +1 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/Ownable.js +3 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/Ownable.js.map +1 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/index.d.ts +2 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/index.d.ts.map +1 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/index.js +3 -0
- package/dist/typechain-types/@openzeppelin/contracts/access/index.js.map +1 -0
- package/dist/typechain-types/@openzeppelin/contracts/index.d.ts +3 -0
- package/dist/typechain-types/@openzeppelin/contracts/index.d.ts.map +1 -0
- package/dist/typechain-types/@openzeppelin/contracts/index.js +3 -0
- package/dist/typechain-types/@openzeppelin/contracts/index.js.map +1 -0
- package/dist/typechain-types/@openzeppelin/index.d.ts +3 -0
- package/dist/typechain-types/@openzeppelin/index.d.ts.map +1 -0
- package/dist/typechain-types/@openzeppelin/index.js +3 -0
- package/dist/typechain-types/@openzeppelin/index.js.map +1 -0
- package/dist/typechain-types/common.d.ts +23 -0
- package/dist/typechain-types/common.d.ts.map +1 -0
- package/dist/typechain-types/common.js +3 -0
- package/dist/typechain-types/common.js.map +1 -0
- package/dist/typechain-types/contracts/index.d.ts +5 -0
- package/dist/typechain-types/contracts/index.d.ts.map +1 -0
- package/dist/typechain-types/contracts/index.js +3 -0
- package/dist/typechain-types/contracts/index.js.map +1 -0
- package/dist/typechain-types/contracts/lzApp/LzApp.d.ts +359 -0
- package/dist/typechain-types/contracts/lzApp/LzApp.d.ts.map +1 -0
- package/dist/typechain-types/contracts/lzApp/LzApp.js +3 -0
- package/dist/typechain-types/contracts/lzApp/LzApp.js.map +1 -0
- package/dist/typechain-types/contracts/lzApp/NonblockingLzApp.d.ts +449 -0
- package/dist/typechain-types/contracts/lzApp/NonblockingLzApp.d.ts.map +1 -0
- package/dist/typechain-types/contracts/lzApp/NonblockingLzApp.js +3 -0
- package/dist/typechain-types/contracts/lzApp/NonblockingLzApp.js.map +1 -0
- package/dist/typechain-types/contracts/lzApp/index.d.ts +3 -0
- package/dist/typechain-types/contracts/lzApp/index.d.ts.map +1 -0
- package/dist/typechain-types/contracts/lzApp/index.js +3 -0
- package/dist/typechain-types/contracts/lzApp/index.js.map +1 -0
- package/dist/typechain-types/contracts/mocks/LZEndpointMock.d.ts +665 -0
- package/dist/typechain-types/contracts/mocks/LZEndpointMock.d.ts.map +1 -0
- package/dist/typechain-types/contracts/mocks/LZEndpointMock.js +3 -0
- package/dist/typechain-types/contracts/mocks/LZEndpointMock.js.map +1 -0
- package/dist/typechain-types/contracts/mocks/index.d.ts +2 -0
- package/dist/typechain-types/contracts/mocks/index.d.ts.map +1 -0
- package/dist/typechain-types/contracts/mocks/index.js +3 -0
- package/dist/typechain-types/contracts/mocks/index.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/index.d.ts +2 -0
- package/dist/typechain-types/factories/@layerzerolabs/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/index.js +31 -0
- package/dist/typechain-types/factories/@layerzerolabs/index.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/index.d.ts +2 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/index.js +31 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/index.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint__factory.d.ts +343 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint__factory.js +456 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint__factory.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver__factory.d.ts +31 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver__factory.js +48 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver__factory.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig__factory.d.ts +65 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig__factory.js +92 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig__factory.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.d.ts +4 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.js +13 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/index.js.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/index.d.ts +2 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/index.js +31 -0
- package/dist/typechain-types/factories/@layerzerolabs/lz-evm-v1-0.7/index.js.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.d.ts +50 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.js +72 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.js.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/index.d.ts +2 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/index.js +9 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/access/index.js.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/index.d.ts +2 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/index.js +31 -0
- package/dist/typechain-types/factories/@openzeppelin/contracts/index.js.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/index.d.ts +2 -0
- package/dist/typechain-types/factories/@openzeppelin/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/@openzeppelin/index.js +31 -0
- package/dist/typechain-types/factories/@openzeppelin/index.js.map +1 -0
- package/dist/typechain-types/factories/contracts/index.d.ts +3 -0
- package/dist/typechain-types/factories/contracts/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/contracts/index.js +32 -0
- package/dist/typechain-types/factories/contracts/index.js.map +1 -0
- package/dist/typechain-types/factories/contracts/lzApp/LzApp__factory.d.ts +354 -0
- package/dist/typechain-types/factories/contracts/lzApp/LzApp__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/contracts/lzApp/LzApp__factory.js +466 -0
- package/dist/typechain-types/factories/contracts/lzApp/LzApp__factory.js.map +1 -0
- package/dist/typechain-types/factories/contracts/lzApp/NonblockingLzApp__factory.d.ts +475 -0
- package/dist/typechain-types/factories/contracts/lzApp/NonblockingLzApp__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/contracts/lzApp/NonblockingLzApp__factory.js +619 -0
- package/dist/typechain-types/factories/contracts/lzApp/NonblockingLzApp__factory.js.map +1 -0
- package/dist/typechain-types/factories/contracts/lzApp/index.d.ts +3 -0
- package/dist/typechain-types/factories/contracts/lzApp/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/contracts/lzApp/index.js +11 -0
- package/dist/typechain-types/factories/contracts/lzApp/index.js.map +1 -0
- package/dist/typechain-types/factories/contracts/mocks/LZEndpointMock__factory.d.ts +738 -0
- package/dist/typechain-types/factories/contracts/mocks/LZEndpointMock__factory.d.ts.map +1 -0
- package/dist/typechain-types/factories/contracts/mocks/LZEndpointMock__factory.js +971 -0
- package/dist/typechain-types/factories/contracts/mocks/LZEndpointMock__factory.js.map +1 -0
- package/dist/typechain-types/factories/contracts/mocks/index.d.ts +2 -0
- package/dist/typechain-types/factories/contracts/mocks/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/contracts/mocks/index.js +9 -0
- package/dist/typechain-types/factories/contracts/mocks/index.js.map +1 -0
- package/dist/typechain-types/factories/index.d.ts +4 -0
- package/dist/typechain-types/factories/index.d.ts.map +1 -0
- package/dist/typechain-types/factories/index.js +33 -0
- package/dist/typechain-types/factories/index.js.map +1 -0
- package/dist/typechain-types/index.d.ts +22 -0
- package/dist/typechain-types/index.d.ts.map +1 -0
- package/dist/typechain-types/index.js +42 -0
- package/dist/typechain-types/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity >=0.6.0;
|
|
4
|
+
pragma experimental ABIEncoderV2;
|
|
5
|
+
|
|
6
|
+
library LzLib {
|
|
7
|
+
// LayerZero communication
|
|
8
|
+
struct CallParams {
|
|
9
|
+
address payable refundAddress;
|
|
10
|
+
address zroPaymentAddress;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//---------------------------------------------------------------------------
|
|
14
|
+
// Address type handling
|
|
15
|
+
|
|
16
|
+
struct AirdropParams {
|
|
17
|
+
uint airdropAmount;
|
|
18
|
+
bytes32 airdropAddress;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildAdapterParams(
|
|
22
|
+
LzLib.AirdropParams memory _airdropParams,
|
|
23
|
+
uint _uaGasLimit
|
|
24
|
+
) internal pure returns (bytes memory adapterParams) {
|
|
25
|
+
if (_airdropParams.airdropAmount == 0 && _airdropParams.airdropAddress == bytes32(0x0)) {
|
|
26
|
+
adapterParams = buildDefaultAdapterParams(_uaGasLimit);
|
|
27
|
+
} else {
|
|
28
|
+
adapterParams = buildAirdropAdapterParams(_uaGasLimit, _airdropParams);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Build Adapter Params
|
|
33
|
+
function buildDefaultAdapterParams(uint _uaGas) internal pure returns (bytes memory) {
|
|
34
|
+
// txType 1
|
|
35
|
+
// bytes [2 32 ]
|
|
36
|
+
// fields [txType extraGas]
|
|
37
|
+
return abi.encodePacked(uint16(1), _uaGas);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function buildAirdropAdapterParams(uint _uaGas, AirdropParams memory _params) internal pure returns (bytes memory) {
|
|
41
|
+
require(_params.airdropAmount > 0, "Airdrop amount must be greater than 0");
|
|
42
|
+
require(_params.airdropAddress != bytes32(0x0), "Airdrop address must be set");
|
|
43
|
+
|
|
44
|
+
// txType 2
|
|
45
|
+
// bytes [2 32 32 bytes[] ]
|
|
46
|
+
// fields [txType extraGas dstNativeAmt dstNativeAddress]
|
|
47
|
+
return abi.encodePacked(uint16(2), _uaGas, _params.airdropAmount, _params.airdropAddress);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getGasLimit(bytes memory _adapterParams) internal pure returns (uint gasLimit) {
|
|
51
|
+
require(_adapterParams.length == 34 || _adapterParams.length > 66, "Invalid adapterParams");
|
|
52
|
+
assembly {
|
|
53
|
+
gasLimit := mload(add(_adapterParams, 34))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Decode Adapter Params
|
|
58
|
+
function decodeAdapterParams(
|
|
59
|
+
bytes memory _adapterParams
|
|
60
|
+
) internal pure returns (uint16 txType, uint uaGas, uint airdropAmount, address payable airdropAddress) {
|
|
61
|
+
require(_adapterParams.length == 34 || _adapterParams.length > 66, "Invalid adapterParams");
|
|
62
|
+
assembly {
|
|
63
|
+
txType := mload(add(_adapterParams, 2))
|
|
64
|
+
uaGas := mload(add(_adapterParams, 34))
|
|
65
|
+
}
|
|
66
|
+
require(txType == 1 || txType == 2, "Unsupported txType");
|
|
67
|
+
require(uaGas > 0, "Gas too low");
|
|
68
|
+
|
|
69
|
+
if (txType == 2) {
|
|
70
|
+
assembly {
|
|
71
|
+
airdropAmount := mload(add(_adapterParams, 66))
|
|
72
|
+
airdropAddress := mload(add(_adapterParams, 86))
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//---------------------------------------------------------------------------
|
|
78
|
+
// Address type handling
|
|
79
|
+
function bytes32ToAddress(bytes32 _bytes32Address) internal pure returns (address _address) {
|
|
80
|
+
return address(uint160(uint(_bytes32Address)));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function addressToBytes32(address _address) internal pure returns (bytes32 _bytes32Address) {
|
|
84
|
+
return bytes32(uint(uint160(_address)));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
6
|
+
import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.sol";
|
|
7
|
+
import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.sol";
|
|
8
|
+
import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.sol";
|
|
9
|
+
import "../util/BytesLib.sol";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* a generic LzReceiver implementation
|
|
13
|
+
*/
|
|
14
|
+
abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
|
|
15
|
+
using BytesLib for bytes;
|
|
16
|
+
|
|
17
|
+
ILayerZeroEndpoint public immutable lzEndpoint;
|
|
18
|
+
mapping(uint16 => bytes) public trustedRemoteLookup;
|
|
19
|
+
mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
|
|
20
|
+
address public precrime;
|
|
21
|
+
|
|
22
|
+
event SetPrecrime(address precrime);
|
|
23
|
+
event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
|
|
24
|
+
event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
|
|
25
|
+
event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);
|
|
26
|
+
|
|
27
|
+
constructor(address _endpoint) {
|
|
28
|
+
lzEndpoint = ILayerZeroEndpoint(_endpoint);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function lzReceive(
|
|
32
|
+
uint16 _srcChainId,
|
|
33
|
+
bytes calldata _srcAddress,
|
|
34
|
+
uint64 _nonce,
|
|
35
|
+
bytes calldata _payload
|
|
36
|
+
) public virtual override {
|
|
37
|
+
// lzReceive must be called by the endpoint for security
|
|
38
|
+
require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller");
|
|
39
|
+
|
|
40
|
+
bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
|
|
41
|
+
// if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.
|
|
42
|
+
require(
|
|
43
|
+
_srcAddress.length == trustedRemote.length &&
|
|
44
|
+
trustedRemote.length > 0 &&
|
|
45
|
+
keccak256(_srcAddress) == keccak256(trustedRemote),
|
|
46
|
+
"LzApp: invalid source sending contract"
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
_blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging
|
|
53
|
+
function _blockingLzReceive(
|
|
54
|
+
uint16 _srcChainId,
|
|
55
|
+
bytes memory _srcAddress,
|
|
56
|
+
uint64 _nonce,
|
|
57
|
+
bytes memory _payload
|
|
58
|
+
) internal virtual;
|
|
59
|
+
|
|
60
|
+
function _lzSend(
|
|
61
|
+
uint16 _dstChainId,
|
|
62
|
+
bytes memory _payload,
|
|
63
|
+
address payable _refundAddress,
|
|
64
|
+
address _zroPaymentAddress,
|
|
65
|
+
bytes memory _adapterParams,
|
|
66
|
+
uint _nativeFee
|
|
67
|
+
) internal virtual {
|
|
68
|
+
bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
|
|
69
|
+
require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
|
|
70
|
+
lzEndpoint.send{value: _nativeFee}(
|
|
71
|
+
_dstChainId,
|
|
72
|
+
trustedRemote,
|
|
73
|
+
_payload,
|
|
74
|
+
_refundAddress,
|
|
75
|
+
_zroPaymentAddress,
|
|
76
|
+
_adapterParams
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function _checkGasLimit(
|
|
81
|
+
uint16 _dstChainId,
|
|
82
|
+
uint16 _type,
|
|
83
|
+
bytes memory _adapterParams,
|
|
84
|
+
uint _extraGas
|
|
85
|
+
) internal view virtual {
|
|
86
|
+
uint providedGasLimit = _getGasLimit(_adapterParams);
|
|
87
|
+
uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;
|
|
88
|
+
require(minGasLimit > 0, "LzApp: minGasLimit not set");
|
|
89
|
+
require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
|
|
93
|
+
require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
|
|
94
|
+
assembly {
|
|
95
|
+
gasLimit := mload(add(_adapterParams, 34))
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//---------------------------UserApplication config----------------------------------------
|
|
100
|
+
function getConfig(
|
|
101
|
+
uint16 _version,
|
|
102
|
+
uint16 _chainId,
|
|
103
|
+
address,
|
|
104
|
+
uint _configType
|
|
105
|
+
) external view returns (bytes memory) {
|
|
106
|
+
return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// generic config for LayerZero user Application
|
|
110
|
+
function setConfig(
|
|
111
|
+
uint16 _version,
|
|
112
|
+
uint16 _chainId,
|
|
113
|
+
uint _configType,
|
|
114
|
+
bytes calldata _config
|
|
115
|
+
) external override onlyOwner {
|
|
116
|
+
lzEndpoint.setConfig(_version, _chainId, _configType, _config);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function setSendVersion(uint16 _version) external override onlyOwner {
|
|
120
|
+
lzEndpoint.setSendVersion(_version);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function setReceiveVersion(uint16 _version) external override onlyOwner {
|
|
124
|
+
lzEndpoint.setReceiveVersion(_version);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
|
|
128
|
+
lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// _path = abi.encodePacked(remoteAddress, localAddress)
|
|
132
|
+
// this function set the trusted path for the cross-chain communication
|
|
133
|
+
function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external onlyOwner {
|
|
134
|
+
trustedRemoteLookup[_srcChainId] = _path;
|
|
135
|
+
emit SetTrustedRemote(_srcChainId, _path);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
|
|
139
|
+
trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
|
|
140
|
+
emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {
|
|
144
|
+
bytes memory path = trustedRemoteLookup[_remoteChainId];
|
|
145
|
+
require(path.length != 0, "LzApp: no trusted path record");
|
|
146
|
+
return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function setPrecrime(address _precrime) external onlyOwner {
|
|
150
|
+
precrime = _precrime;
|
|
151
|
+
emit SetPrecrime(_precrime);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {
|
|
155
|
+
require(_minGas > 0, "LzApp: invalid minGas");
|
|
156
|
+
minDstGasLookup[_dstChainId][_packetType] = _minGas;
|
|
157
|
+
emit SetMinDstGas(_dstChainId, _packetType, _minGas);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//--------------------------- VIEW FUNCTION ----------------------------------------
|
|
161
|
+
function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
|
|
162
|
+
bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
|
|
163
|
+
return keccak256(trustedSource) == keccak256(_srcAddress);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
|
|
5
|
+
import "./LzApp.sol";
|
|
6
|
+
import "../util/ExcessivelySafeCall.sol";
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel
|
|
10
|
+
* this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking
|
|
11
|
+
* NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)
|
|
12
|
+
*/
|
|
13
|
+
abstract contract NonblockingLzApp is LzApp {
|
|
14
|
+
using ExcessivelySafeCall for address;
|
|
15
|
+
|
|
16
|
+
constructor(address _endpoint) LzApp(_endpoint) {}
|
|
17
|
+
|
|
18
|
+
mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;
|
|
19
|
+
|
|
20
|
+
event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
|
|
21
|
+
event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);
|
|
22
|
+
|
|
23
|
+
// overriding the virtual function in LzReceiver
|
|
24
|
+
function _blockingLzReceive(
|
|
25
|
+
uint16 _srcChainId,
|
|
26
|
+
bytes memory _srcAddress,
|
|
27
|
+
uint64 _nonce,
|
|
28
|
+
bytes memory _payload
|
|
29
|
+
) internal virtual override {
|
|
30
|
+
(bool success, bytes memory reason) = address(this).excessivelySafeCall(
|
|
31
|
+
gasleft(),
|
|
32
|
+
150,
|
|
33
|
+
abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)
|
|
34
|
+
);
|
|
35
|
+
// try-catch all errors/exceptions
|
|
36
|
+
if (!success) {
|
|
37
|
+
_storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function _storeFailedMessage(
|
|
42
|
+
uint16 _srcChainId,
|
|
43
|
+
bytes memory _srcAddress,
|
|
44
|
+
uint64 _nonce,
|
|
45
|
+
bytes memory _payload,
|
|
46
|
+
bytes memory _reason
|
|
47
|
+
) internal virtual {
|
|
48
|
+
failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
|
|
49
|
+
emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function nonblockingLzReceive(
|
|
53
|
+
uint16 _srcChainId,
|
|
54
|
+
bytes calldata _srcAddress,
|
|
55
|
+
uint64 _nonce,
|
|
56
|
+
bytes calldata _payload
|
|
57
|
+
) public virtual {
|
|
58
|
+
// only internal transaction
|
|
59
|
+
require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp");
|
|
60
|
+
_nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//@notice override this function
|
|
64
|
+
function _nonblockingLzReceive(
|
|
65
|
+
uint16 _srcChainId,
|
|
66
|
+
bytes memory _srcAddress,
|
|
67
|
+
uint64 _nonce,
|
|
68
|
+
bytes memory _payload
|
|
69
|
+
) internal virtual;
|
|
70
|
+
|
|
71
|
+
function retryMessage(
|
|
72
|
+
uint16 _srcChainId,
|
|
73
|
+
bytes calldata _srcAddress,
|
|
74
|
+
uint64 _nonce,
|
|
75
|
+
bytes calldata _payload
|
|
76
|
+
) public payable virtual {
|
|
77
|
+
// assert there is message to retry
|
|
78
|
+
bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
|
|
79
|
+
require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
|
|
80
|
+
require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
|
|
81
|
+
// clear the stored message
|
|
82
|
+
failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
|
|
83
|
+
// execute the message. revert if it fails again
|
|
84
|
+
_nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
|
|
85
|
+
emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
|
|
86
|
+
}
|
|
87
|
+
}
|