@layerzerolabs/lz-evm-oapp-v2 2.0.2
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/artifacts/contracts/oapp/OApp.sol/OApp.json +332 -0
- package/artifacts/contracts/oapp/OAppCore.sol/OAppCore.json +195 -0
- package/artifacts/contracts/oapp/OAppReceiver.sol/OAppReceiver.json +316 -0
- package/artifacts/contracts/oapp/OAppSender.sol/OAppSender.json +211 -0
- package/artifacts/contracts/oapp/examples/OmniCounter.sol/MsgCodec.json +10 -0
- package/artifacts/contracts/oapp/examples/OmniCounter.sol/OmniCounter.json +874 -0
- package/artifacts/contracts/oapp/examples/OmniCounterPreCrime.sol/OmniCounterPreCrime.json +373 -0
- package/artifacts/contracts/oapp/interfaces/IOAppComposer.sol/IOAppComposer.json +44 -0
- package/artifacts/contracts/oapp/interfaces/IOAppCore.sol/IOAppCore.json +143 -0
- package/artifacts/contracts/oapp/interfaces/IOAppMsgInspector.sol/IOAppMsgInspector.json +51 -0
- package/artifacts/contracts/oapp/interfaces/IOAppOptionsType3.sol/IOAppOptionsType3.json +111 -0
- package/artifacts/contracts/oapp/libs/OAppOptionsType3.sol/OAppOptionsType3.json +187 -0
- package/artifacts/contracts/oapp/libs/OptionsBuilder.sol/OptionsBuilder.json +38 -0
- package/artifacts/contracts/oft/OFT.sol/OFT.json +1466 -0
- package/artifacts/contracts/oft/OFTAdapter.sol/OFTAdapter.json +1204 -0
- package/artifacts/contracts/oft/OFTCore.sol/OFTCore.json +1170 -0
- package/artifacts/contracts/oft/interfaces/IOFT.sol/IOFT.json +472 -0
- package/artifacts/contracts/oft/libs/OFTComposeMsgCodec.sol/OFTComposeMsgCodec.json +10 -0
- package/artifacts/contracts/oft/libs/OFTMsgCodec.sol/OFTMsgCodec.json +10 -0
- package/artifacts/contracts/precrime/OAppPreCrimeSimulator.sol/OAppPreCrimeSimulator.json +277 -0
- package/artifacts/contracts/precrime/PreCrime.sol/PreCrime.json +352 -0
- package/artifacts/contracts/precrime/extensions/PreCrimeE1.sol/PreCrimeE1.json +352 -0
- package/artifacts/contracts/precrime/interfaces/IOAppPreCrimeSimulator.sol/IOAppPreCrimeSimulator.json +175 -0
- package/artifacts/contracts/precrime/interfaces/IPreCrime.sol/IPreCrime.json +188 -0
- package/artifacts/contracts/precrime/libs/Packet.sol/PacketDecoder.json +10 -0
- package/contracts/oapp/OApp.sol +39 -0
- package/contracts/oapp/OAppCore.sol +68 -0
- package/contracts/oapp/OAppReceiver.sol +101 -0
- package/contracts/oapp/OAppSender.sol +124 -0
- package/contracts/oapp/examples/OmniCounter.sol +283 -0
- package/contracts/oapp/examples/OmniCounterPreCrime.sol +102 -0
- package/contracts/oapp/interfaces/IOAppComposer.sol +12 -0
- package/contracts/oapp/interfaces/IOAppCore.sol +51 -0
- package/contracts/oapp/interfaces/IOAppMsgInspector.sol +22 -0
- package/contracts/oapp/interfaces/IOAppOptionsType3.sol +43 -0
- package/contracts/oapp/libs/OAppOptionsType3.sol +82 -0
- package/contracts/oapp/libs/OptionsBuilder.sol +200 -0
- package/contracts/oft/OFT.sol +116 -0
- package/contracts/oft/OFTAdapter.sol +131 -0
- package/contracts/oft/OFTCore.sol +456 -0
- package/contracts/oft/OFTPrecrime.sol +99 -0
- package/contracts/oft/interfaces/IOFT.sol +168 -0
- package/contracts/oft/libs/OFTComposeMsgCodec.sol +91 -0
- package/contracts/oft/libs/OFTMsgCodec.sol +83 -0
- package/contracts/precrime/OAppPreCrimeSimulator.sol +125 -0
- package/contracts/precrime/PreCrime.sol +208 -0
- package/contracts/precrime/extensions/PreCrimeE1.sol +30 -0
- package/contracts/precrime/interfaces/IOAppPreCrimeSimulator.sol +55 -0
- package/contracts/precrime/interfaces/IPreCrime.sol +40 -0
- package/contracts/precrime/libs/Packet.sol +61 -0
- package/package.json +35 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
// import { IOApp } from "../../interfaces/IOApp.sol";
|
|
6
|
+
// import { IOFT } from "./interfaces/IOFT.sol";
|
|
7
|
+
// import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
8
|
+
// import { OFTAdapter } from "./OFTAdapter.sol";
|
|
9
|
+
|
|
10
|
+
//contract OFTPreCrime is PreCrime {
|
|
11
|
+
// address public oft;
|
|
12
|
+
// uint256 public EXPECTED_GLOBAL_SUPPLY;
|
|
13
|
+
//
|
|
14
|
+
// constructor(address _endpoint, address _oft) PreCrime(_endpoint) {
|
|
15
|
+
// oft = _oft;
|
|
16
|
+
// }
|
|
17
|
+
//
|
|
18
|
+
// struct SimulationResult {
|
|
19
|
+
// uint256 totalSupplyLD;
|
|
20
|
+
// bool isAdapter;
|
|
21
|
+
// }
|
|
22
|
+
//
|
|
23
|
+
// // @dev only necessary when its exclusive 'OFT', NOT 'OFTAdapter' type
|
|
24
|
+
// // sum of all tokens in the oft network, it can change, but this will need to be updated for pre-Crime to pass
|
|
25
|
+
// function setGlobalSupply(uint256 _globalSupply) public onlyPreCrimeAdmin {
|
|
26
|
+
// EXPECTED_GLOBAL_SUPPLY = _globalSupply;
|
|
27
|
+
// }
|
|
28
|
+
//
|
|
29
|
+
// // -------------------------------
|
|
30
|
+
// // PreCrime
|
|
31
|
+
// function _receiver() internal view override returns (address) {
|
|
32
|
+
// return address(oft);
|
|
33
|
+
// }
|
|
34
|
+
//
|
|
35
|
+
// function _preCrime(bytes[] memory _simulation) internal view override returns (uint16 code, bytes memory reason) {
|
|
36
|
+
// uint256 globalSupply;
|
|
37
|
+
// uint256 expectedGlobalSupply = EXPECTED_GLOBAL_SUPPLY;
|
|
38
|
+
//
|
|
39
|
+
// // @dev indicates that there is an 'OFTAdapter' on one of the chains, not necessarily this local chain
|
|
40
|
+
// bool isOFTAdapter;
|
|
41
|
+
//
|
|
42
|
+
// for (uint256 i = 0; i < _simulation.length; i++) {
|
|
43
|
+
// SimulationResult memory result = abi.decode(_simulation[i], (SimulationResult));
|
|
44
|
+
//
|
|
45
|
+
// if (result.isAdapter) {
|
|
46
|
+
// // @dev does not support multiple' 'OFTAdapter' contracts for a given oft mesh
|
|
47
|
+
// if (isOFTAdapter) return (CODE_PRECRIME_FAILURE, "OFTPreCrime: multiple OFTAdapters found");
|
|
48
|
+
// isOFTAdapter = true;
|
|
49
|
+
//
|
|
50
|
+
// expectedGlobalSupply = result.totalSupplyLD;
|
|
51
|
+
// } else {
|
|
52
|
+
// globalSupply += result.totalSupplyLD;
|
|
53
|
+
// }
|
|
54
|
+
// }
|
|
55
|
+
//
|
|
56
|
+
// if (isOFTAdapter && globalSupply > expectedGlobalSupply) {
|
|
57
|
+
// // @dev expectedGlobal supply for an 'OFTAdapter' can be slightly higher due to users sending tokens direct
|
|
58
|
+
// // to the OFTAdapter contract, cant check explicitly "=="
|
|
59
|
+
// return (CODE_PRECRIME_FAILURE, "OFTPreCrime: globalSupply > expectedGlobalSupply");
|
|
60
|
+
// } else if (globalSupply != expectedGlobalSupply) {
|
|
61
|
+
// // @dev exclusively 'OFT', NOT 'OFTAdapter' instances, balances should be exactly "=="
|
|
62
|
+
// return (CODE_PRECRIME_FAILURE, "OFTPreCrime: globalSupply != expectedGlobalSupply");
|
|
63
|
+
// } else {
|
|
64
|
+
// return (CODE_SUCCESS, "");
|
|
65
|
+
// }
|
|
66
|
+
// }
|
|
67
|
+
//
|
|
68
|
+
// function simulationCallback() external view override returns (bytes memory result) {
|
|
69
|
+
// address token = IOFT(oft).token();
|
|
70
|
+
//
|
|
71
|
+
// // @dev checks if the corresponding _oft on this chain is an adapter version, or returns false if its regular 'OFT'
|
|
72
|
+
// // eg. 'OFTAdapter' lock/unlock tokens from an external token contract, vs. regular 'OFT' mints/burns
|
|
73
|
+
// bool isAdapter = token != oft;
|
|
74
|
+
//
|
|
75
|
+
// // @dev for 'OFTAdapter' the total supply is the total amount locked, otherwise its the totalSupply of oft tokens on the chain
|
|
76
|
+
// uint256 totalSupply = isAdapter ? IERC20(token).balanceOf(oft) : IERC20(oft).totalSupply();
|
|
77
|
+
//
|
|
78
|
+
// return abi.encode(SimulationResult(totalSupply, isAdapter));
|
|
79
|
+
// }
|
|
80
|
+
//
|
|
81
|
+
// function _simulate(Packet[] calldata _packets) internal override returns (uint16 code, bytes memory simulation) {
|
|
82
|
+
// (bool success, bytes memory result) = oft.call{value: msg.value}(
|
|
83
|
+
// abi.encodeWithSelector(IOApp.lzReceiveAndRevert.selector, _packets)
|
|
84
|
+
// );
|
|
85
|
+
// require(!success, "OFTPreCrime: simulationCallback should be called via revert");
|
|
86
|
+
//
|
|
87
|
+
// (, result) = _parseRevertResult(result, LzReceiveRevert.selector);
|
|
88
|
+
// return (CODE_SUCCESS, result);
|
|
89
|
+
// }
|
|
90
|
+
//
|
|
91
|
+
// // @dev need to ensure that all preCrimePeers are present inside of the results passed into _checkResultsCompleteness()
|
|
92
|
+
// // when checking oft preCrime we always want every simulation/result from the remote peers
|
|
93
|
+
// function _getPreCrimePeers(
|
|
94
|
+
// Packet[] calldata /*_packets*/
|
|
95
|
+
// ) internal view override returns (uint32[] memory eids, bytes32[] memory peers) {
|
|
96
|
+
// // @dev assumes that the preCrimeEids is the full list of oft eids for this oft mesh
|
|
97
|
+
// return (preCrimeEids, preCrimePeers);
|
|
98
|
+
// }
|
|
99
|
+
//}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
import { MessagingReceipt, MessagingFee } from "../../oapp/OAppSender.sol";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @dev Struct representing token parameters for the OFT send() operation.
|
|
9
|
+
*/
|
|
10
|
+
struct SendParam {
|
|
11
|
+
uint32 dstEid; // Destination endpoint ID.
|
|
12
|
+
bytes32 to; // Recipient address.
|
|
13
|
+
uint256 amountToSendLD; // Amount to send in local decimals.
|
|
14
|
+
uint256 minAmountToCreditLD; // Minimum amount to credit in local decimals.
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @dev Struct representing OFT limit information.
|
|
19
|
+
* @dev These amounts can change dynamically and are up the the specific oft implementation.
|
|
20
|
+
*/
|
|
21
|
+
struct OFTLimit {
|
|
22
|
+
uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient.
|
|
23
|
+
uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient.
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @dev Struct representing OFT receipt information.
|
|
28
|
+
*/
|
|
29
|
+
struct OFTReceipt {
|
|
30
|
+
uint256 amountDebitLD; // Amount of tokens ACTUALLY debited in local decimals.
|
|
31
|
+
// @dev Does not guarantee the recipient will receive the credit amount, as remote implementations can vary depending on the OFT
|
|
32
|
+
// eg. fees COULD be applied on the remote side, so the recipient may receive less than amountCreditLD
|
|
33
|
+
uint256 amountCreditLD; // Amount of tokens to be credited on the remote side.
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @dev Struct representing OFT fee details.
|
|
38
|
+
* @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI.
|
|
39
|
+
*/
|
|
40
|
+
struct OFTFeeDetail {
|
|
41
|
+
uint256 feeAmountLD; // Amount of the fee in local decimals.
|
|
42
|
+
string description; // Description of the fee.
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @title IOFT
|
|
47
|
+
* @dev Interface for the OftChain (OFT) token.
|
|
48
|
+
* @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well.
|
|
49
|
+
*/
|
|
50
|
+
interface IOFT {
|
|
51
|
+
// Custom error messages
|
|
52
|
+
error InvalidLocalDecimals();
|
|
53
|
+
error SlippageExceeded(uint256 amountToCreditLD, uint256 minAmountToCreditLD);
|
|
54
|
+
|
|
55
|
+
// Events
|
|
56
|
+
event MsgInspectorSet(address inspector);
|
|
57
|
+
event OFTSent(
|
|
58
|
+
bytes32 indexed guid, // GUID of the OFT message.
|
|
59
|
+
address indexed fromAddress, // Address of the sender on the src chain.
|
|
60
|
+
uint256 amountDebitedLD, // Amount of tokens ACTUALLY debited from the sender in local decimals.
|
|
61
|
+
uint256 amountToCreditLD, // Amount of tokens to be credited on the remote side in local decimals.
|
|
62
|
+
bytes composeMsg // Composed message for the send() operation.
|
|
63
|
+
);
|
|
64
|
+
event OFTReceived(
|
|
65
|
+
bytes32 indexed guid, // GUID of the OFT message.
|
|
66
|
+
address indexed toAddress, // Address of the recipient on the dst chain.
|
|
67
|
+
uint256 amountToCreditLD, // Amount of tokens to be credited on the remote side in local decimals.
|
|
68
|
+
uint256 amountReceivedLD // Amount of tokens ACTUALLY received by the recipient in local decimals.
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @notice Retrieves the major and minor version of the OFT.
|
|
73
|
+
* @return major The major version.
|
|
74
|
+
* @return minor The minor version.
|
|
75
|
+
*
|
|
76
|
+
* @dev major version: Indicates a cross-chain compatible msg encoding with other OFTs.
|
|
77
|
+
* @dev minor version: Indicates a version within the local chains context. eg. OFTAdapter vs. OFT
|
|
78
|
+
* @dev For example, if a new feature is added to the OFT contract, the minor version will be incremented.
|
|
79
|
+
* @dev If a new feature is added to the OFT cross-chain msg encoding, the major version will be incremented.
|
|
80
|
+
* ie. localOFT version(1,1) CAN send messages to remoteOFT version(1,2)
|
|
81
|
+
*/
|
|
82
|
+
function oftVersion() external view returns (uint64 major, uint64 minor);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @notice Retrieves the address of the token associated with the OFT.
|
|
86
|
+
* @return token The address of the ERC20 token implementation.
|
|
87
|
+
*/
|
|
88
|
+
function token() external view returns (address);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @notice Retrieves the shared decimals of the OFT.
|
|
92
|
+
* @return sharedDecimals The shared decimals of the OFT.
|
|
93
|
+
*/
|
|
94
|
+
function sharedDecimals() external view returns (uint8);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @notice Sets the message inspector address for the OFT.
|
|
98
|
+
* @param _msgInspector The address of the message inspector.
|
|
99
|
+
*/
|
|
100
|
+
function setMsgInspector(address _msgInspector) external;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @notice Retrieves the address of the message inspector.
|
|
104
|
+
* @return msgInspector The address of the message inspector.
|
|
105
|
+
*/
|
|
106
|
+
function msgInspector() external view returns (address);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @notice Provides a quote for OFT-related operations.
|
|
110
|
+
* @param _sendParam The parameters for the send operation.
|
|
111
|
+
* @param _oftCmd The OFT command to be executed.
|
|
112
|
+
* @return limit The OFT limit information.
|
|
113
|
+
* @return oftFeeDetails The details of OFT fees.
|
|
114
|
+
* @return receipt The OFT receipt information.
|
|
115
|
+
*/
|
|
116
|
+
function quoteOFT(
|
|
117
|
+
SendParam calldata _sendParam,
|
|
118
|
+
bytes calldata _oftCmd
|
|
119
|
+
) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @notice Provides a quote for the send() operation.
|
|
123
|
+
* @param _sendParam The parameters for the send() operation.
|
|
124
|
+
* @param _extraOptions Additional options supplied by the caller to be used in the LayerZero message.
|
|
125
|
+
* @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
|
|
126
|
+
* @param _composeMsg The composed message for the send() operation.
|
|
127
|
+
* @param _oftCmd The OFT command to be executed.
|
|
128
|
+
* @return fee The calculated LayerZero messaging fee from the send() operation.
|
|
129
|
+
*
|
|
130
|
+
* @dev MessagingFee: LayerZero msg fee
|
|
131
|
+
* - nativeFee: The native fee.
|
|
132
|
+
* - lzTokenFee: The lzToken fee.
|
|
133
|
+
*/
|
|
134
|
+
function quoteSend(
|
|
135
|
+
SendParam calldata _sendParam,
|
|
136
|
+
bytes calldata _extraOptions,
|
|
137
|
+
bool _payInLzToken,
|
|
138
|
+
bytes calldata _composeMsg,
|
|
139
|
+
bytes calldata _oftCmd
|
|
140
|
+
) external view returns (MessagingFee memory);
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @notice Executes the send() operation.
|
|
144
|
+
* @param _sendParam The parameters for the send operation.
|
|
145
|
+
* @param _extraOptions Additional options supplied by the caller to be used in the LayerZero message.
|
|
146
|
+
* @param _fee The fee information supplied by the caller.
|
|
147
|
+
* - nativeFee: The native fee.
|
|
148
|
+
* - lzTokenFee: The lzToken fee.
|
|
149
|
+
* @param _refundAddress The address to receive any excess funds from fees etc. on the src.
|
|
150
|
+
* @param _composeMsg The composed message for the send() operation.
|
|
151
|
+
* @param _oftCmd The OFT command to be executed.
|
|
152
|
+
* @return receipt The LayerZero messaging receipt from the send() operation.
|
|
153
|
+
* @return oftReceipt The OFT receipt information.
|
|
154
|
+
*
|
|
155
|
+
* @dev MessagingReceipt: LayerZero msg receipt
|
|
156
|
+
* - guid: The unique identifier for the sent message.
|
|
157
|
+
* - nonce: The nonce of the sent message.
|
|
158
|
+
* - fee: The LayerZero fee incurred for the message.
|
|
159
|
+
*/
|
|
160
|
+
function send(
|
|
161
|
+
SendParam calldata _sendParam,
|
|
162
|
+
bytes calldata _extraOptions,
|
|
163
|
+
MessagingFee calldata _fee,
|
|
164
|
+
address _refundAddress,
|
|
165
|
+
bytes calldata _composeMsg,
|
|
166
|
+
bytes calldata _oftCmd
|
|
167
|
+
) external payable returns (MessagingReceipt memory, OFTReceipt memory);
|
|
168
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
library OFTComposeMsgCodec {
|
|
6
|
+
// Offset constants for decoding composed messages
|
|
7
|
+
uint8 private constant NONCE_OFFSET = 8;
|
|
8
|
+
uint8 private constant SRC_EID_OFFSET = 12;
|
|
9
|
+
uint8 private constant AMOUNT_LD_OFFSET = 44;
|
|
10
|
+
uint8 private constant COMPOSE_FROM_OFFSET = 76;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @dev Encodes a OFT composed message.
|
|
14
|
+
* @param _nonce The nonce value.
|
|
15
|
+
* @param _srcEid The source endpoint ID.
|
|
16
|
+
* @param _amountLD The amount in local decimals.
|
|
17
|
+
* @param _composeMsg The composed message.
|
|
18
|
+
* @return _msg The encoded Composed message.
|
|
19
|
+
*/
|
|
20
|
+
function encode(
|
|
21
|
+
uint64 _nonce,
|
|
22
|
+
uint32 _srcEid,
|
|
23
|
+
uint256 _amountLD,
|
|
24
|
+
bytes memory _composeMsg // 0x[composeFrom][composeMsg]
|
|
25
|
+
) internal pure returns (bytes memory _msg) {
|
|
26
|
+
_msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @dev Retrieves the nonce from the composed message.
|
|
31
|
+
* @param _msg The message.
|
|
32
|
+
* @return The nonce value.
|
|
33
|
+
*/
|
|
34
|
+
function nonce(bytes calldata _msg) internal pure returns (uint64) {
|
|
35
|
+
return uint64(bytes8(_msg[:NONCE_OFFSET]));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @dev Retrieves the source endpoint ID from the composed message.
|
|
40
|
+
* @param _msg The message.
|
|
41
|
+
* @return The source endpoint ID.
|
|
42
|
+
*/
|
|
43
|
+
function srcEid(bytes calldata _msg) internal pure returns (uint32) {
|
|
44
|
+
return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET]));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @dev Retrieves the amount in local decimals from the composed message.
|
|
49
|
+
* @param _msg The message.
|
|
50
|
+
* @return The amount in local decimals.
|
|
51
|
+
*/
|
|
52
|
+
function amountLD(bytes calldata _msg) internal pure returns (uint256) {
|
|
53
|
+
return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET]));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @dev Retrieves the composeFrom value from the composed message.
|
|
58
|
+
* @param _msg The message.
|
|
59
|
+
* @return The composeFrom value.
|
|
60
|
+
*/
|
|
61
|
+
function composeFrom(bytes calldata _msg) internal pure returns (bytes32) {
|
|
62
|
+
return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @dev Retrieves the composed message.
|
|
67
|
+
* @param _msg The message.
|
|
68
|
+
* @return The composed message.
|
|
69
|
+
*/
|
|
70
|
+
function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) {
|
|
71
|
+
return _msg[COMPOSE_FROM_OFFSET:];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @dev Converts an address to bytes32.
|
|
76
|
+
* @param _addr The address to convert.
|
|
77
|
+
* @return The bytes32 representation of the address.
|
|
78
|
+
*/
|
|
79
|
+
function addressToBytes32(address _addr) internal pure returns (bytes32) {
|
|
80
|
+
return bytes32(uint256(uint160(_addr)));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @dev Converts bytes32 to an address.
|
|
85
|
+
* @param _b The bytes32 value to convert.
|
|
86
|
+
* @return The address representation of bytes32.
|
|
87
|
+
*/
|
|
88
|
+
function bytes32ToAddress(bytes32 _b) internal pure returns (address) {
|
|
89
|
+
return address(uint160(uint256(_b)));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
library OFTMsgCodec {
|
|
6
|
+
// Offset constants for encoding and decoding OFT messages
|
|
7
|
+
uint8 private constant SEND_TO_OFFSET = 32;
|
|
8
|
+
uint8 private constant SEND_AMOUNT_SD_OFFSET = 40;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @dev Encodes an OFT LayerZero message.
|
|
12
|
+
* @param _sendTo The recipient address.
|
|
13
|
+
* @param _amountShared The amount in shared decimals.
|
|
14
|
+
* @param _composeMsg The composed message.
|
|
15
|
+
* @return _msg The encoded message.
|
|
16
|
+
* @return hasCompose A boolean indicating whether the message has a composed payload.
|
|
17
|
+
*/
|
|
18
|
+
function encode(
|
|
19
|
+
bytes32 _sendTo,
|
|
20
|
+
uint64 _amountShared,
|
|
21
|
+
bytes memory _composeMsg
|
|
22
|
+
) internal view returns (bytes memory _msg, bool hasCompose) {
|
|
23
|
+
hasCompose = _composeMsg.length > 0;
|
|
24
|
+
// @dev Remote chains will want to know the composed function caller ie. msg.sender on the src.
|
|
25
|
+
_msg = hasCompose
|
|
26
|
+
? abi.encodePacked(_sendTo, _amountShared, addressToBytes32(msg.sender), _composeMsg)
|
|
27
|
+
: abi.encodePacked(_sendTo, _amountShared);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @dev Checks if the OFT message is composed.
|
|
32
|
+
* @param _msg The OFT message.
|
|
33
|
+
* @return A boolean indicating whether the message is composed.
|
|
34
|
+
*/
|
|
35
|
+
function isComposed(bytes calldata _msg) internal pure returns (bool) {
|
|
36
|
+
return _msg.length > SEND_AMOUNT_SD_OFFSET;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @dev Retrieves the recipient address from the OFT message.
|
|
41
|
+
* @param _msg The OFT message.
|
|
42
|
+
* @return The recipient address.
|
|
43
|
+
*/
|
|
44
|
+
function sendTo(bytes calldata _msg) internal pure returns (bytes32) {
|
|
45
|
+
return bytes32(_msg[:SEND_TO_OFFSET]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @dev Retrieves the amount in shared decimals from the OFT message.
|
|
50
|
+
* @param _msg The OFT message.
|
|
51
|
+
* @return The amount in shared decimals.
|
|
52
|
+
*/
|
|
53
|
+
function amountSD(bytes calldata _msg) internal pure returns (uint64) {
|
|
54
|
+
return uint64(bytes8(_msg[SEND_TO_OFFSET:SEND_AMOUNT_SD_OFFSET]));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @dev Retrieves the composed message from the OFT message.
|
|
59
|
+
* @param _msg The OFT message.
|
|
60
|
+
* @return The composed message.
|
|
61
|
+
*/
|
|
62
|
+
function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) {
|
|
63
|
+
return _msg[SEND_AMOUNT_SD_OFFSET:];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @dev Converts an address to bytes32.
|
|
68
|
+
* @param _addr The address to convert.
|
|
69
|
+
* @return The bytes32 representation of the address.
|
|
70
|
+
*/
|
|
71
|
+
function addressToBytes32(address _addr) internal pure returns (bytes32) {
|
|
72
|
+
return bytes32(uint256(uint160(_addr)));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @dev Converts bytes32 to an address.
|
|
77
|
+
* @param _b The bytes32 value to convert.
|
|
78
|
+
* @return The address representation of bytes32.
|
|
79
|
+
*/
|
|
80
|
+
function bytes32ToAddress(bytes32 _b) internal pure returns (address) {
|
|
81
|
+
return address(uint160(uint256(_b)));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
|
|
6
|
+
import { IPreCrime } from "./interfaces/IPreCrime.sol";
|
|
7
|
+
import { IOAppPreCrimeSimulator, InboundPacket, Origin } from "./interfaces/IOAppPreCrimeSimulator.sol";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @title OAppPreCrimeSimulator
|
|
11
|
+
* @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp.
|
|
12
|
+
*/
|
|
13
|
+
abstract contract OAppPreCrimeSimulator is IOAppPreCrimeSimulator, Ownable {
|
|
14
|
+
// The address of the preCrime implementation.
|
|
15
|
+
address public preCrime;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @dev Retrieves the address of the OApp contract.
|
|
19
|
+
* @return The address of the OApp contract.
|
|
20
|
+
*
|
|
21
|
+
* @dev The simulator contract is the base contract for the OApp by default.
|
|
22
|
+
* @dev If the simulator is a separate contract, override this function.
|
|
23
|
+
*/
|
|
24
|
+
function oApp() external view virtual returns (address) {
|
|
25
|
+
return address(this);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @dev Sets the preCrime contract address.
|
|
30
|
+
* @param _preCrime The address of the preCrime contract.
|
|
31
|
+
*/
|
|
32
|
+
function setPreCrime(address _preCrime) public virtual onlyOwner {
|
|
33
|
+
preCrime = _preCrime;
|
|
34
|
+
emit PreCrimeSet(_preCrime);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @dev Interface for pre-crime simulations. Always reverts at the end with the simulation results.
|
|
39
|
+
* @param _packets An array of InboundPacket objects representing received packets to be delivered.
|
|
40
|
+
*
|
|
41
|
+
* @dev WARNING: MUST revert at the end with the simulation results.
|
|
42
|
+
* @dev Gives the preCrime implementation the ability to mock sending packets to the lzReceive function,
|
|
43
|
+
* WITHOUT actually executing them.
|
|
44
|
+
*/
|
|
45
|
+
function lzReceiveAndRevert(InboundPacket[] calldata _packets) public payable virtual {
|
|
46
|
+
for (uint256 i = 0; i < _packets.length; i++) {
|
|
47
|
+
InboundPacket calldata packet = _packets[i];
|
|
48
|
+
|
|
49
|
+
// Ignore packets that are not from trusted peers.
|
|
50
|
+
if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue;
|
|
51
|
+
|
|
52
|
+
// @dev Because a verifier is calling this function, it doesnt have access to executor params:
|
|
53
|
+
// - address _executor
|
|
54
|
+
// - bytes calldata _extraData
|
|
55
|
+
// preCrime will NOT work for OApps that rely on these two parameters inside of their _lzReceive().
|
|
56
|
+
// They are instead stubbed to default values, address(0) and bytes("")
|
|
57
|
+
// @dev Calling this.lzReceiveSimulate removes ability for assembly return 0 callstack exit,
|
|
58
|
+
// which would cause the revert to be ignored.
|
|
59
|
+
this.lzReceiveSimulate{ value: packet.value }(
|
|
60
|
+
packet.origin,
|
|
61
|
+
packet.guid,
|
|
62
|
+
packet.message,
|
|
63
|
+
packet.executor,
|
|
64
|
+
packet.extraData
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// @dev Revert with the simulation results. msg.sender must implement IPreCrime.buildSimulationResult().
|
|
69
|
+
revert SimulationResult(IPreCrime(msg.sender).buildSimulationResult());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @dev Is effectively an internal function because msg.sender must be address(this).
|
|
74
|
+
* Allows resetting the call stack for 'internal' calls.
|
|
75
|
+
* @param _origin The origin information containing the source endpoint and sender address.
|
|
76
|
+
* - srcEid: The source chain endpoint ID.
|
|
77
|
+
* - sender: The sender address on the src chain.
|
|
78
|
+
* - nonce: The nonce of the message.
|
|
79
|
+
* @param _guid The unique identifier of the packet.
|
|
80
|
+
* @param _message The message payload of the packet.
|
|
81
|
+
* @param _executor The executor address for the packet.
|
|
82
|
+
* @param _extraData Additional data for the packet.
|
|
83
|
+
*/
|
|
84
|
+
function lzReceiveSimulate(
|
|
85
|
+
Origin calldata _origin,
|
|
86
|
+
bytes32 _guid,
|
|
87
|
+
bytes calldata _message,
|
|
88
|
+
address _executor,
|
|
89
|
+
bytes calldata _extraData
|
|
90
|
+
) external payable virtual {
|
|
91
|
+
// @dev Ensure ONLY can be called 'internally'.
|
|
92
|
+
if (msg.sender != address(this)) revert OnlySelf();
|
|
93
|
+
_lzReceiveSimulate(_origin, _guid, _message, _executor, _extraData);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @dev Internal function to handle the OAppPreCrimeSimulator simulated receive.
|
|
98
|
+
* @param _origin The origin information.
|
|
99
|
+
* - srcEid: The source chain endpoint ID.
|
|
100
|
+
* - sender: The sender address from the src chain.
|
|
101
|
+
* - nonce: The nonce of the LayerZero message.
|
|
102
|
+
* @param _guid The GUID of the LayerZero message.
|
|
103
|
+
* @param _message The LayerZero message.
|
|
104
|
+
* @param _executor The address of the off-chain executor.
|
|
105
|
+
* @param _extraData Arbitrary data passed by the msg executor.
|
|
106
|
+
*
|
|
107
|
+
* @dev Enables the preCrime simulator to mock sending lzReceive() messages,
|
|
108
|
+
* routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver.
|
|
109
|
+
*/
|
|
110
|
+
function _lzReceiveSimulate(
|
|
111
|
+
Origin calldata _origin,
|
|
112
|
+
bytes32 _guid,
|
|
113
|
+
bytes calldata _message,
|
|
114
|
+
address _executor,
|
|
115
|
+
bytes calldata _extraData
|
|
116
|
+
) internal virtual;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @dev checks if the specified peer is considered 'trusted' by the OApp.
|
|
120
|
+
* @param _eid The endpoint Id to check.
|
|
121
|
+
* @param _peer The peer to check.
|
|
122
|
+
* @return Whether the peer passed is considered 'trusted' by the OApp.
|
|
123
|
+
*/
|
|
124
|
+
function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool);
|
|
125
|
+
}
|