Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a util function in MessageReceiverApp to deal with the "receving native token" issue #191

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/interfaces/IBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
pragma solidity >=0.8.0;

interface IBridge {
function nativeWrap() external view returns (address);

function send(
address _receiver,
address _token,
Expand Down
2 changes: 2 additions & 0 deletions contracts/message/apps/BatchTransfer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ contract BatchTransfer is MessageSenderApp, MessageReceiverApp {
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
TransferRequest memory transfer = abi.decode((_message), (TransferRequest));
wrapBridgeOutToken(_token, _amount);
uint256 totalAmt;
for (uint256 i = 0; i < transfer.accounts.length; i++) {
IERC20(_token).safeTransfer(transfer.accounts[i], transfer.amounts[i]);
Expand Down Expand Up @@ -150,6 +151,7 @@ contract BatchTransfer is MessageSenderApp, MessageReceiverApp {
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
TransferRequest memory transfer = abi.decode((_message), (TransferRequest));
wrapBridgeOutToken(_token, _amount);
IERC20(_token).safeTransfer(transfer.sender, _amount);
bytes memory message = abi.encode(TransferReceipt({nonce: transfer.nonce, status: TransferStatus.Fail}));
sendMessage(_sender, _srcChainId, message, msg.value);
Expand Down
2 changes: 2 additions & 0 deletions contracts/message/apps/MsgTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ contract MsgTest is MessageSenderApp, MessageReceiverApp {
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
(address receiver, bytes memory message) = abi.decode((_message), (address, bytes));
wrapBridgeOutToken(_token, _amount);
IERC20(_token).safeTransfer(receiver, _amount);
emit MessageReceivedWithTransfer(_token, _amount, _sender, _srcChainId, receiver, message);
return ExecutionStatus.Success;
Expand All @@ -73,6 +74,7 @@ contract MsgTest is MessageSenderApp, MessageReceiverApp {
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
(address receiver, bytes memory message) = abi.decode((_message), (address, bytes));
wrapBridgeOutToken(_token, _amount);
IERC20(_token).safeTransfer(receiver, _amount);
emit Refunded(receiver, _token, _amount, message);
return ExecutionStatus.Success;
Expand Down
1 change: 1 addition & 0 deletions contracts/message/apps/TransferSwap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ contract TransferSwap is MessageSenderApp, MessageReceiverApp {
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
SwapRequest memory m = abi.decode((_message), (SwapRequest));
wrapBridgeOutToken(_token, _amount);
require(_token == m.swap.path[0], "bridged token must be the same as the first token in destination swap path");
bytes32 id = _computeSwapRequestId(m.receiver, _srcChainId, uint64(block.chainid), _message);
uint256 dstAmount;
Expand Down
23 changes: 23 additions & 0 deletions contracts/message/framework/MessageReceiverApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
pragma solidity 0.8.9;

import "../interfaces/IMessageReceiverApp.sol";
import "../interfaces/IMessageBus.sol";
import "../../interfaces/IBridge.sol";
import "../../interfaces/IWETH.sol";
import "./MessageBusAddress.sol";

abstract contract MessageReceiverApp is IMessageReceiverApp, MessageBusAddress {
Expand Down Expand Up @@ -81,4 +84,24 @@ abstract contract MessageReceiverApp is IMessageReceiverApp, MessageBusAddress {
bytes calldata _message,
address _executor
) external payable virtual override onlyMessageBus returns (ExecutionStatus) {}

/**
* @notice util function that checks whether the bridge out token is native and wraps it
* @dev when the bridged token is a native or wrapped native token, whether your contracts receives native/wrapped token depends on whether
* the "nativeWrap" field is set in the Bridge contract. An easy but sometimes gas-inefficient way to deal with this is to always check and
* wrap the bridge out token using this function.
* note Assumption: only the liquidity bridge is capable of sending a native wrap
* @param _bridgeOutToken token out from liquidity bridge
* @param _amount amount of token
*/
function wrapBridgeOutToken(address _bridgeOutToken, uint256 _amount) internal {
address bridge = IMessageBus(messageBus).liquidityBridge();
if (bridge == address(0)) {
return;
}
address nativeWrap = IBridge(bridge).nativeWrap();
if (_bridgeOutToken == nativeWrap) {
IWETH(nativeWrap).deposit{value: _amount}();
}
}
}