Skip to content

Commit 8f433b8

Browse files
authored
fix: dst chain is the hub chain (#1576)
Signed-off-by: shankar <shankar@layerzerolabs.org>
1 parent 5a16ea5 commit 8f433b8

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

packages/ovault-composer/contracts/OVaultComposer.sol

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.s
88

99
import { IOFT, SendParam, MessagingFee } from "@layerzerolabs/oft-evm/contracts/interfaces/IOFT.sol";
1010
import { IOAppCore } from "@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.sol";
11+
import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
1112
import { OFTComposeMsgCodec } from "@layerzerolabs/oft-evm/contracts/libs/OFTComposeMsgCodec.sol";
1213

1314
import { IOVaultComposer, FailedMessage, FailedState } from "./interfaces/IOVaultComposer.sol";
@@ -22,6 +23,7 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
2223
address public immutable SHARE_OFT;
2324
address public immutable OVAULT;
2425
address public immutable ENDPOINT;
26+
uint32 public immutable COMPOSER_EID;
2527

2628
mapping(bytes32 guid => FailedMessage) public failedMessages;
2729

@@ -36,6 +38,7 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
3638
SHARE_OFT = IOVault(_ovault).SHARE_OFT();
3739
ASSET_OFT = IOVault(_ovault).ASSET_OFT();
3840
ENDPOINT = address(IOAppCore(ASSET_OFT).endpoint());
41+
COMPOSER_EID = ILayerZeroEndpointV2(ENDPOINT).eid();
3942

4043
// Approve the adapter to spend the share tokens held by this contract
4144
IERC20(share).approve(OVAULT, type(uint256).max);
@@ -129,6 +132,10 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
129132

130133
/// @dev Dirty swapping amountLD and minAmountLD to 1e18 and 0 to avoid Slippage issue on the target OFT quoteSend()
131134
function validateTargetOFTConfig(address _oft, SendParam memory _sendParam) external view {
135+
if (COMPOSER_EID == _sendParam.dstEid) {
136+
return;
137+
}
138+
132139
_sendParam.amountLD = 1e18;
133140
_sendParam.minAmountLD = 0;
134141

@@ -138,6 +145,18 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
138145
/// @dev External call for try...catch logic in lzCompose()
139146
function send(address _oft, SendParam calldata _sendParam) external payable nonReentrant {
140147
if (msg.sender != address(this)) revert OnlySelf(msg.sender);
148+
if (_sendParam.dstEid == COMPOSER_EID) {
149+
address _receiver = _sendParam.to.bytes32ToAddress();
150+
uint256 _amountLD = _sendParam.amountLD;
151+
IERC20 token = IERC20(IOFT(_oft).token());
152+
token.transfer(_receiver, _amountLD);
153+
if (msg.value > 0) {
154+
(bool sent, ) = _receiver.call{ value: msg.value }("");
155+
require(sent, "Failed to send Ether");
156+
}
157+
emit SentOnHub(_receiver, _oft, _amountLD);
158+
return;
159+
}
141160
_send(_oft, _sendParam);
142161
}
143162

packages/ovault-composer/contracts/interfaces/IOVaultComposer.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface IOVaultComposer is IOAppComposer {
2222
/// ========================== EVENTS =====================================
2323
event DecodeFailed(bytes32 indexed guid, address indexed oft, bytes message);
2424
event Sent(bytes32 indexed guid, address indexed oft);
25+
event SentOnHub(address indexed receiver, address indexed oft, uint256 amountLD);
2526
event SendFailed(bytes32 indexed guid, address indexed oft);
2627
event Refunded(bytes32 indexed guid, address indexed oft);
2728
event Retried(bytes32 indexed guid, address indexed oft);

packages/ovault-composer/test/composer/OVaultComposer_Unit.t.sol

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,51 @@ contract OVaultComposerUnitTest is OVaultComposerBaseTest {
8787
assertEq(shareOFT_arb.totalSupply(), 0);
8888
}
8989

90+
function test_lzCompose_pass_on_hub() public {
91+
bytes32 guid = _randomGUID();
92+
assetOFT_arb.mint(address(OVaultComposerArb), TOKENS_TO_SEND);
93+
94+
SendParam memory internalSendParam = SendParam(
95+
OVaultComposerArb.COMPOSER_EID(),
96+
addressToBytes32(userA),
97+
TOKENS_TO_SEND,
98+
0,
99+
OPTIONS_LZRECEIVE_2M,
100+
"",
101+
""
102+
);
103+
104+
bytes memory composeMsg = _createComposePayload(ETH_EID, internalSendParam, TOKENS_TO_SEND, userA);
105+
106+
vm.expectEmit(true, true, true, true, address(assetOFT_arb));
107+
emit IERC20.Transfer(address(OVaultComposerArb), address(oVault_arb), TOKENS_TO_SEND);
108+
109+
vm.expectEmit(true, true, true, true, address(shareOFT_arb));
110+
emit IERC20.Transfer(address(0), address(OVaultComposerArb), TOKENS_TO_SEND);
111+
112+
vm.expectEmit(true, true, true, true, address(oVault_arb));
113+
emit IERC4626Adapter.Deposit(
114+
address(OVaultComposerArb),
115+
address(OVaultComposerArb),
116+
TOKENS_TO_SEND,
117+
TOKENS_TO_SEND
118+
);
119+
120+
vm.expectEmit(true, true, true, true, address(OVaultComposerArb));
121+
emit IOVaultComposer.SentOnHub(userA, address(shareOFT_arb), TOKENS_TO_SEND);
122+
123+
assertEq(assetOFT_arb.totalSupply(), assetOFT_arb.balanceOf(address(OVaultComposerArb)), TOKENS_TO_SEND);
124+
assertEq(shareOFT_arb.totalSupply(), 0);
125+
126+
vm.prank(arbEndpoint);
127+
OVaultComposerArb.lzCompose{ value: 1 ether }(address(assetOFT_arb), guid, composeMsg, arbExecutor, "");
128+
129+
assertEq(uint256(OVaultComposerArb.failedGuidState(guid)), uint256(FailedState.NotFound));
130+
131+
assertEq(assetOFT_arb.totalSupply(), assetOFT_arb.balanceOf(address(oVault_arb)), TOKENS_TO_SEND);
132+
assertEq(shareOFT_arb.totalSupply(), shareOFT_arb.balanceOf(address(userA)), TOKENS_TO_SEND);
133+
}
134+
90135
function test_lzCompose_fail_invalid_payload() public {
91136
bytes32 guid = _randomGUID();
92137
assetOFT_arb.mint(address(OVaultComposerArb), TOKENS_TO_SEND);

0 commit comments

Comments
 (0)