@layerzerolabs/lz-evm-oapp-v2 2.0.23 → 2.0.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/artifacts/contracts/oapp/OApp.sol/OApp.json +18 -0
- package/artifacts/contracts/oapp/OAppCore.sol/OAppCore.json +5 -0
- package/artifacts/contracts/oapp/OAppReceiver.sol/OAppReceiver.json +18 -0
- package/artifacts/contracts/oapp/OAppSender.sol/OAppSender.json +5 -0
- package/artifacts/contracts/oapp/examples/OmniCounter.sol/MsgCodec.json +2 -2
- package/artifacts/contracts/oapp/examples/OmniCounter.sol/OmniCounter.json +21 -3
- package/artifacts/contracts/oapp/examples/OmniCounterPreCrime.sol/OmniCounterPreCrime.json +2 -7
- package/artifacts/contracts/oapp/interfaces/IOAppCore.sol/IOAppCore.json +5 -0
- package/artifacts/contracts/oapp/interfaces/IOAppReceiver.sol/IOAppReceiver.json +134 -0
- package/artifacts/contracts/oft/OFT.sol/OFT.json +108 -99
- package/artifacts/contracts/oft/OFTAdapter.sol/OFTAdapter.json +108 -107
- package/artifacts/contracts/oft/OFTCore.sol/OFTCore.json +108 -73
- package/artifacts/contracts/oft/interfaces/IOFT.sol/IOFT.json +80 -102
- package/contracts/oapp/OApp.sol +4 -4
- package/contracts/oapp/OAppCore.sol +8 -6
- package/contracts/oapp/OAppReceiver.sol +14 -3
- package/contracts/oapp/OAppSender.sol +1 -1
- package/contracts/oapp/examples/OmniCounter.sol +1 -1
- package/contracts/oapp/examples/OmniCounterPreCrime.sol +1 -1
- package/contracts/oapp/interfaces/IOAppCore.sol +1 -0
- package/contracts/oapp/interfaces/IOAppReceiver.sol +15 -0
- package/contracts/oft/OFT.sol +39 -55
- package/contracts/oft/OFTAdapter.sol +52 -65
- package/contracts/oft/OFTCore.sol +59 -133
- package/contracts/oft/interfaces/IOFT.sol +35 -55
- package/contracts/precrime/PreCrime.sol +1 -2
- package/contracts/precrime/extensions/PreCrimeE1.sol +1 -1
- package/package.json +9 -9
package/contracts/oapp/OApp.sol
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
pragma solidity ^0.8.20;
|
|
4
4
|
|
|
5
|
-
// @dev Import the 'MessagingFee' so it's exposed to OApp implementers
|
|
5
|
+
// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers
|
|
6
6
|
// solhint-disable-next-line no-unused-import
|
|
7
|
-
import { OAppSender, MessagingFee } from "./OAppSender.sol";
|
|
7
|
+
import { OAppSender, MessagingFee, MessagingReceipt } from "./OAppSender.sol";
|
|
8
8
|
// @dev Import the 'Origin' so it's exposed to OApp implementers
|
|
9
9
|
// solhint-disable-next-line no-unused-import
|
|
10
10
|
import { OAppReceiver, Origin } from "./OAppReceiver.sol";
|
|
@@ -18,9 +18,9 @@ abstract contract OApp is OAppSender, OAppReceiver {
|
|
|
18
18
|
/**
|
|
19
19
|
* @dev Constructor to initialize the OApp with the provided endpoint and owner.
|
|
20
20
|
* @param _endpoint The address of the LOCAL LayerZero endpoint.
|
|
21
|
-
* @param
|
|
21
|
+
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
|
|
22
22
|
*/
|
|
23
|
-
constructor(address _endpoint, address
|
|
23
|
+
constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* @notice Retrieves the OApp version information.
|
|
@@ -17,14 +17,17 @@ abstract contract OAppCore is IOAppCore, Ownable {
|
|
|
17
17
|
mapping(uint32 eid => bytes32 peer) public peers;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* @dev Constructor to initialize the OAppCore with the provided endpoint and
|
|
20
|
+
* @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.
|
|
21
21
|
* @param _endpoint The address of the LOCAL Layer Zero endpoint.
|
|
22
|
-
* @param
|
|
22
|
+
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
|
|
23
|
+
*
|
|
24
|
+
* @dev The delegate typically should be set as the owner of the contract.
|
|
23
25
|
*/
|
|
24
|
-
constructor(address _endpoint, address
|
|
25
|
-
_transferOwnership(_owner);
|
|
26
|
+
constructor(address _endpoint, address _delegate) {
|
|
26
27
|
endpoint = ILayerZeroEndpointV2(_endpoint);
|
|
27
|
-
|
|
28
|
+
|
|
29
|
+
if (_delegate == address(0)) revert InvalidDelegate();
|
|
30
|
+
endpoint.setDelegate(_delegate);
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
/**
|
|
@@ -60,7 +63,6 @@ abstract contract OAppCore is IOAppCore, Ownable {
|
|
|
60
63
|
*
|
|
61
64
|
* @dev Only the owner/admin of the OApp can call this function.
|
|
62
65
|
* @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract.
|
|
63
|
-
* @dev Defaults to the owner of the OApp.
|
|
64
66
|
*/
|
|
65
67
|
function setDelegate(address _delegate) public onlyOwner {
|
|
66
68
|
endpoint.setDelegate(_delegate);
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
pragma solidity ^0.8.20;
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { IOAppReceiver, Origin } from "./interfaces/IOAppReceiver.sol";
|
|
6
6
|
import { OAppCore } from "./OAppCore.sol";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @title OAppReceiver
|
|
10
10
|
* @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.
|
|
11
11
|
*/
|
|
12
|
-
abstract contract OAppReceiver is
|
|
12
|
+
abstract contract OAppReceiver is IOAppReceiver, OAppCore {
|
|
13
13
|
// Custom error message for when the caller is not the registered endpoint/
|
|
14
14
|
error OnlyEndpoint(address addr);
|
|
15
15
|
|
|
@@ -23,13 +23,24 @@ abstract contract OAppReceiver is ILayerZeroReceiver, OAppCore {
|
|
|
23
23
|
* @return receiverVersion The version of the OAppReceiver.sol contract.
|
|
24
24
|
*
|
|
25
25
|
* @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented.
|
|
26
|
-
* ie. this is a
|
|
26
|
+
* ie. this is a RECEIVE only OApp.
|
|
27
27
|
* @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions.
|
|
28
28
|
*/
|
|
29
29
|
function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {
|
|
30
30
|
return (0, RECEIVER_VERSION);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.
|
|
35
|
+
* @return sender The address responsible for 'sending' composeMsg's to the Endpoint.
|
|
36
|
+
*
|
|
37
|
+
* @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
|
|
38
|
+
* @dev The default sender IS the OApp implementer.
|
|
39
|
+
*/
|
|
40
|
+
function composeMsgSender() public view virtual returns (address sender) {
|
|
41
|
+
return address(this);
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
/**
|
|
34
45
|
* @notice Checks if the path initialization is allowed based on the provided origin.
|
|
35
46
|
* @param origin The origin information containing the source endpoint and sender address.
|
|
@@ -27,7 +27,7 @@ abstract contract OAppSender is OAppCore {
|
|
|
27
27
|
* @return receiverVersion The version of the OAppReceiver.sol contract.
|
|
28
28
|
*
|
|
29
29
|
* @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.
|
|
30
|
-
* ie. this is a
|
|
30
|
+
* ie. this is a SEND only OApp.
|
|
31
31
|
* @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions
|
|
32
32
|
*/
|
|
33
33
|
function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {
|
|
@@ -57,7 +57,7 @@ contract OmniCounter is ILayerZeroComposer, OApp, OAppPreCrimeSimulator {
|
|
|
57
57
|
mapping(uint32 srcEid => uint256 count) public inboundCount;
|
|
58
58
|
mapping(uint32 dstEid => uint256 count) public outboundCount;
|
|
59
59
|
|
|
60
|
-
constructor(address _endpoint, address
|
|
60
|
+
constructor(address _endpoint, address _delegate) OApp(_endpoint, _delegate) {
|
|
61
61
|
admin = msg.sender;
|
|
62
62
|
eid = ILayerZeroEndpointV2(_endpoint).eid();
|
|
63
63
|
}
|
|
@@ -13,7 +13,7 @@ contract OmniCounterPreCrime is PreCrime {
|
|
|
13
13
|
uint256 outboundCount;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
constructor(address _endpoint, address _counter
|
|
16
|
+
constructor(address _endpoint, address _counter) PreCrime(_endpoint, _counter) {}
|
|
17
17
|
|
|
18
18
|
function buildSimulationResult() external view override returns (bytes memory) {
|
|
19
19
|
address payable payableSimulator = payable(simulator);
|
|
@@ -12,6 +12,7 @@ interface IOAppCore {
|
|
|
12
12
|
error OnlyPeer(uint32 eid, bytes32 sender);
|
|
13
13
|
error NoPeer(uint32 eid);
|
|
14
14
|
error InvalidEndpointCall();
|
|
15
|
+
error InvalidDelegate();
|
|
15
16
|
|
|
16
17
|
// Event emitted when a peer (OApp) is set for a corresponding endpoint
|
|
17
18
|
event PeerSet(uint32 eid, bytes32 peer);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import { ILayerZeroReceiver, Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol";
|
|
5
|
+
|
|
6
|
+
interface IOAppReceiver is ILayerZeroReceiver {
|
|
7
|
+
/**
|
|
8
|
+
* @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.
|
|
9
|
+
* @return sender The address responsible for 'sending' composeMsg's to the Endpoint.
|
|
10
|
+
*
|
|
11
|
+
* @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
|
|
12
|
+
* @dev The default sender IS the OApp implementer.
|
|
13
|
+
*/
|
|
14
|
+
function composeMsgSender() external view returns (address sender);
|
|
15
|
+
}
|
package/contracts/oft/OFT.sol
CHANGED
|
@@ -3,40 +3,39 @@
|
|
|
3
3
|
pragma solidity ^0.8.20;
|
|
4
4
|
|
|
5
5
|
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
6
|
-
import { OFTCore } from "./OFTCore.sol";
|
|
6
|
+
import { IOFT, OFTCore } from "./OFTCore.sol";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @title OFT Contract
|
|
10
10
|
* @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract.
|
|
11
11
|
*/
|
|
12
|
-
contract OFT is OFTCore, ERC20 {
|
|
12
|
+
abstract contract OFT is OFTCore, ERC20 {
|
|
13
13
|
/**
|
|
14
14
|
* @dev Constructor for the OFT contract.
|
|
15
15
|
* @param _name The name of the OFT.
|
|
16
16
|
* @param _symbol The symbol of the OFT.
|
|
17
17
|
* @param _lzEndpoint The LayerZero endpoint address.
|
|
18
|
-
* @param
|
|
18
|
+
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
|
|
19
19
|
*/
|
|
20
20
|
constructor(
|
|
21
21
|
string memory _name,
|
|
22
22
|
string memory _symbol,
|
|
23
23
|
address _lzEndpoint,
|
|
24
|
-
address
|
|
25
|
-
) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint,
|
|
24
|
+
address _delegate
|
|
25
|
+
) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint, _delegate) {}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* @
|
|
29
|
-
* @return
|
|
30
|
-
* @return
|
|
28
|
+
* @notice Retrieves interfaceID and the version of the OFT.
|
|
29
|
+
* @return interfaceId The interface ID.
|
|
30
|
+
* @return version The version.
|
|
31
31
|
*
|
|
32
|
-
* @dev
|
|
33
|
-
* @dev
|
|
34
|
-
* @dev
|
|
35
|
-
*
|
|
36
|
-
* ie. localOFT version(1,1) CAN send messages to remoteOFT version(1,2)
|
|
32
|
+
* @dev interfaceId: This specific interface ID is '0x02e49c2c'.
|
|
33
|
+
* @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
|
|
34
|
+
* @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
|
|
35
|
+
* ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
|
|
37
36
|
*/
|
|
38
|
-
function oftVersion() external pure returns (
|
|
39
|
-
return (
|
|
37
|
+
function oftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) {
|
|
38
|
+
return (type(IOFT).interfaceId, 1);
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
/**
|
|
@@ -50,67 +49,52 @@ contract OFT is OFTCore, ERC20 {
|
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
|
-
* @
|
|
54
|
-
* @
|
|
55
|
-
*
|
|
56
|
-
* @
|
|
57
|
-
* @return amountDebitedLD The amount of tokens ACTUALLY debited in local decimals.
|
|
58
|
-
* @return amountToCreditLD The amount of tokens to credit in local decimals.
|
|
52
|
+
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
|
|
53
|
+
* @return requiresApproval Needs approval of the underlying token implementation.
|
|
54
|
+
*
|
|
55
|
+
* @dev In the case of OFT where the contract IS the token, approval is NOT required.
|
|
59
56
|
*/
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
uint256 _minAmountToCreditLD,
|
|
63
|
-
uint32 _dstEid
|
|
64
|
-
) internal virtual override returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
|
|
65
|
-
(amountDebitedLD, amountToCreditLD) = _debitView(_amountToSendLD, _minAmountToCreditLD, _dstEid);
|
|
66
|
-
|
|
67
|
-
// @dev In NON-default OFT, amountDebited could be 100, with a 10% fee, the credited amount is 90,
|
|
68
|
-
// therefore amountDebited CAN differ from amountToCredit.
|
|
69
|
-
|
|
70
|
-
// @dev Default OFT burns on src.
|
|
71
|
-
_burn(msg.sender, amountDebitedLD);
|
|
57
|
+
function approvalRequired() external pure virtual returns (bool) {
|
|
58
|
+
return false;
|
|
72
59
|
}
|
|
73
60
|
|
|
74
61
|
/**
|
|
75
|
-
* @dev Burns tokens
|
|
76
|
-
* @param
|
|
62
|
+
* @dev Burns tokens from the sender's specified balance.
|
|
63
|
+
* @param _amountLD The amount of tokens to send in local decimals.
|
|
64
|
+
* @param _minAmountLD The minimum amount to send in local decimals.
|
|
77
65
|
* @param _dstEid The destination chain ID.
|
|
78
|
-
* @return
|
|
79
|
-
* @return
|
|
66
|
+
* @return amountSentLD The amount sent in local decimals.
|
|
67
|
+
* @return amountReceivedLD The amount received in local decimals on the remote.
|
|
80
68
|
*/
|
|
81
|
-
function
|
|
82
|
-
uint256
|
|
69
|
+
function _debit(
|
|
70
|
+
uint256 _amountLD,
|
|
71
|
+
uint256 _minAmountLD,
|
|
83
72
|
uint32 _dstEid
|
|
84
|
-
) internal virtual override returns (uint256
|
|
85
|
-
|
|
86
|
-
// @dev This SHOULD be done atomically, otherwise any caller can spend tokens that are owned by the contract.
|
|
87
|
-
// @dev In the NON-default case where fees are stored in the contract, there should be a value reserved via a global state.
|
|
88
|
-
// eg. balanceOf(address(this)) - accruedFees;
|
|
89
|
-
(amountDebitedLD, amountToCreditLD) = _debitView(balanceOf(address(this)), _minAmountToReceiveLD, _dstEid);
|
|
73
|
+
) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) {
|
|
74
|
+
(amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid);
|
|
90
75
|
|
|
91
|
-
// @dev
|
|
92
|
-
|
|
76
|
+
// @dev In NON-default OFT, amountSentLD could be 100, with a 10% fee, the amountReceivedLD amount is 90,
|
|
77
|
+
// therefore amountSentLD CAN differ from amountReceivedLD.
|
|
93
78
|
|
|
94
|
-
// @dev
|
|
95
|
-
|
|
96
|
-
// If you want to refund this dust, will need to add another function to return it.
|
|
79
|
+
// @dev Default OFT burns on src.
|
|
80
|
+
_burn(msg.sender, amountSentLD);
|
|
97
81
|
}
|
|
98
82
|
|
|
99
83
|
/**
|
|
100
84
|
* @dev Credits tokens to the specified address.
|
|
101
85
|
* @param _to The address to credit the tokens to.
|
|
102
|
-
* @param
|
|
86
|
+
* @param _amountLD The amount of tokens to credit in local decimals.
|
|
103
87
|
* @dev _srcEid The source chain ID.
|
|
104
88
|
* @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals.
|
|
105
89
|
*/
|
|
106
90
|
function _credit(
|
|
107
91
|
address _to,
|
|
108
|
-
uint256
|
|
92
|
+
uint256 _amountLD,
|
|
109
93
|
uint32 /*_srcEid*/
|
|
110
94
|
) internal virtual override returns (uint256 amountReceivedLD) {
|
|
111
95
|
// @dev Default OFT mints on dst.
|
|
112
|
-
_mint(_to,
|
|
113
|
-
// @dev In the case of NON-default OFT, the
|
|
114
|
-
return
|
|
96
|
+
_mint(_to, _amountLD);
|
|
97
|
+
// @dev In the case of NON-default OFT, the _amountLD MIGHT not be == amountReceivedLD.
|
|
98
|
+
return _amountLD;
|
|
115
99
|
}
|
|
116
100
|
}
|
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.20;
|
|
|
4
4
|
|
|
5
5
|
import { IERC20Metadata, IERC20 } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
|
|
6
6
|
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
7
|
-
import { OFTCore } from "./OFTCore.sol";
|
|
7
|
+
import { IOFT, OFTCore } from "./OFTCore.sol";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @title OFTAdapter Contract
|
|
@@ -12,44 +12,42 @@ import { OFTCore } from "./OFTCore.sol";
|
|
|
12
12
|
*
|
|
13
13
|
* @dev For existing ERC20 tokens, this can be used to convert the token to crosschain compatibility.
|
|
14
14
|
* @dev WARNING: ONLY 1 of these should exist for a given global mesh,
|
|
15
|
-
* unless you make a NON-default implementation of OFT and needs to be done very carefully
|
|
15
|
+
* unless you make a NON-default implementation of OFT and needs to be done very carefully.
|
|
16
|
+
* @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
|
|
17
|
+
* IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
|
|
18
|
+
* a pre/post balance check will need to be done to calculate the amountSentLD/amountReceivedLD.
|
|
16
19
|
*/
|
|
17
|
-
contract OFTAdapter is OFTCore {
|
|
20
|
+
abstract contract OFTAdapter is OFTCore {
|
|
18
21
|
using SafeERC20 for IERC20;
|
|
19
22
|
|
|
20
23
|
IERC20 internal immutable innerToken;
|
|
21
24
|
|
|
22
|
-
// @dev The amount of tokens locked inside this contract.
|
|
23
|
-
// @dev This SHOULD equal the total amount of OFTs in circulation on all the NON OFTAdapter chains
|
|
24
|
-
uint256 public outboundAmount;
|
|
25
|
-
|
|
26
25
|
/**
|
|
27
26
|
* @dev Constructor for the OFTAdapter contract.
|
|
28
27
|
* @param _token The address of the ERC-20 token to be adapted.
|
|
29
28
|
* @param _lzEndpoint The LayerZero endpoint address.
|
|
30
|
-
* @param
|
|
29
|
+
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
|
|
31
30
|
*/
|
|
32
31
|
constructor(
|
|
33
32
|
address _token,
|
|
34
33
|
address _lzEndpoint,
|
|
35
|
-
address
|
|
36
|
-
) OFTCore(IERC20Metadata(_token).decimals(), _lzEndpoint,
|
|
34
|
+
address _delegate
|
|
35
|
+
) OFTCore(IERC20Metadata(_token).decimals(), _lzEndpoint, _delegate) {
|
|
37
36
|
innerToken = IERC20(_token);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
/**
|
|
41
|
-
* @
|
|
42
|
-
* @return
|
|
43
|
-
* @return
|
|
40
|
+
* @notice Retrieves interfaceID and the version of the OFT.
|
|
41
|
+
* @return interfaceId The interface ID.
|
|
42
|
+
* @return version The version.
|
|
44
43
|
*
|
|
45
|
-
* @dev
|
|
46
|
-
* @dev
|
|
47
|
-
* @dev
|
|
48
|
-
*
|
|
49
|
-
* ie. localOFT version(1,1) CAN send messages to remoteOFT version(1,2)
|
|
44
|
+
* @dev interfaceId: This specific interface ID is '0x02e49c2c'.
|
|
45
|
+
* @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
|
|
46
|
+
* @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
|
|
47
|
+
* ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
|
|
50
48
|
*/
|
|
51
|
-
function oftVersion() external pure returns (
|
|
52
|
-
return (
|
|
49
|
+
function oftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) {
|
|
50
|
+
return (type(IOFT).interfaceId, 1);
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
/**
|
|
@@ -58,74 +56,63 @@ contract OFTAdapter is OFTCore {
|
|
|
58
56
|
*
|
|
59
57
|
* @dev In the case of OFTAdapter, address(this) and erc20 are NOT the same contract.
|
|
60
58
|
*/
|
|
61
|
-
function token()
|
|
59
|
+
function token() external view returns (address) {
|
|
62
60
|
return address(innerToken);
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
/**
|
|
66
|
-
* @
|
|
67
|
-
* @
|
|
68
|
-
*
|
|
69
|
-
* @
|
|
70
|
-
* @
|
|
71
|
-
* @return amountToCreditLD The amount of tokens to credit in local decimals.
|
|
64
|
+
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
|
|
65
|
+
* @return requiresApproval Needs approval of the underlying token implementation.
|
|
66
|
+
*
|
|
67
|
+
* @dev In the case of default OFTAdapter, approval is required.
|
|
68
|
+
* @dev In non-default OFTAdapter contracts with something like mint and burn privileges, it would NOT need approval.
|
|
72
69
|
*/
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
uint256 _minAmountToCreditLD,
|
|
76
|
-
uint32 _dstEid
|
|
77
|
-
) internal virtual override returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
|
|
78
|
-
(amountDebitedLD, amountToCreditLD) = _debitView(_amountToSendLD, _minAmountToCreditLD, _dstEid);
|
|
79
|
-
// @dev msg.sender will need to approve this amountLD of tokens to be locked inside of the contract.
|
|
80
|
-
// @dev Move all of the debited tokens into this contract.
|
|
81
|
-
innerToken.safeTransferFrom(msg.sender, address(this), amountDebitedLD);
|
|
82
|
-
|
|
83
|
-
// @dev In NON-default OFTAdapter, amountDebited could be 100, with a 10% fee, the credited amount is 90,
|
|
84
|
-
// so technically the amountToCredit would be locked as outboundAmount. Therefore amountDebited CAN differ from amountToCredit.
|
|
85
|
-
// @dev Due to OFTs containing both push/pull methods, the reserved amount needs to be tracked so _debitThis() cant spend it.
|
|
86
|
-
outboundAmount += amountToCreditLD;
|
|
70
|
+
function approvalRequired() external pure virtual returns (bool) {
|
|
71
|
+
return true;
|
|
87
72
|
}
|
|
88
73
|
|
|
89
74
|
/**
|
|
90
|
-
* @dev
|
|
91
|
-
* @param
|
|
75
|
+
* @dev Burns tokens from the sender's specified balance, ie. pull method.
|
|
76
|
+
* @param _amountLD The amount of tokens to send in local decimals.
|
|
77
|
+
* @param _minAmountLD The minimum amount to send in local decimals.
|
|
92
78
|
* @param _dstEid The destination chain ID.
|
|
93
|
-
* @return
|
|
94
|
-
* @return
|
|
79
|
+
* @return amountSentLD The amount sent in local decimals.
|
|
80
|
+
* @return amountReceivedLD The amount received in local decimals on the remote.
|
|
81
|
+
*
|
|
82
|
+
* @dev msg.sender will need to approve this _amountLD of tokens to be locked inside of the contract.
|
|
83
|
+
* @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
|
|
84
|
+
* IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
|
|
85
|
+
* a pre/post balance check will need to be done to calculate the amountReceivedLD.
|
|
95
86
|
*/
|
|
96
|
-
function
|
|
97
|
-
uint256
|
|
87
|
+
function _debit(
|
|
88
|
+
uint256 _amountLD,
|
|
89
|
+
uint256 _minAmountLD,
|
|
98
90
|
uint32 _dstEid
|
|
99
|
-
) internal virtual override returns (uint256
|
|
100
|
-
|
|
101
|
-
// @dev
|
|
102
|
-
|
|
103
|
-
(amountDebitedLD, amountToCreditLD) = _debitView(availableToSend, _minAmountToCreditLD, _dstEid);
|
|
104
|
-
|
|
105
|
-
// @dev Due to OFTs containing both push/pull methods, the reserved amount needs to be tracked so _debitThis() cant spend it.
|
|
106
|
-
outboundAmount += amountToCreditLD;
|
|
107
|
-
|
|
108
|
-
// @dev When sending tokens direct to the OFTAdapter contract,
|
|
109
|
-
// there is NOT a default mechanism to capture the dust that MIGHT get left in the contract.
|
|
110
|
-
// If you want to refund this dust, will need to add another function to return it.
|
|
91
|
+
) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) {
|
|
92
|
+
(amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid);
|
|
93
|
+
// @dev Lock tokens by moving them into this contract from the caller.
|
|
94
|
+
innerToken.safeTransferFrom(msg.sender, address(this), amountSentLD);
|
|
111
95
|
}
|
|
112
96
|
|
|
113
97
|
/**
|
|
114
98
|
* @dev Credits tokens to the specified address.
|
|
115
99
|
* @param _to The address to credit the tokens to.
|
|
116
|
-
* @param
|
|
100
|
+
* @param _amountLD The amount of tokens to credit in local decimals.
|
|
117
101
|
* @dev _srcEid The source chain ID.
|
|
118
102
|
* @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals.
|
|
103
|
+
*
|
|
104
|
+
* @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
|
|
105
|
+
* IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
|
|
106
|
+
* a pre/post balance check will need to be done to calculate the amountReceivedLD.
|
|
119
107
|
*/
|
|
120
108
|
function _credit(
|
|
121
109
|
address _to,
|
|
122
|
-
uint256
|
|
110
|
+
uint256 _amountLD,
|
|
123
111
|
uint32 /*_srcEid*/
|
|
124
112
|
) internal virtual override returns (uint256 amountReceivedLD) {
|
|
125
|
-
outboundAmount -= _amountToCreditLD;
|
|
126
113
|
// @dev Unlock the tokens and transfer to the recipient.
|
|
127
|
-
innerToken.safeTransfer(_to,
|
|
128
|
-
// @dev In the case of NON-default OFTAdapter, the
|
|
129
|
-
return
|
|
114
|
+
innerToken.safeTransfer(_to, _amountLD);
|
|
115
|
+
// @dev In the case of NON-default OFTAdapter, the amountLD MIGHT not be == amountReceivedLD.
|
|
116
|
+
return _amountLD;
|
|
130
117
|
}
|
|
131
118
|
}
|