Repository navigation
Expand file tree
/
Copy pathMsgExampleBasicTransfer.sol
More file actions
82 lines (72 loc) · 3.14 KB
/
Copy pathMsgExampleBasicTransfer.sol
File metadata and controls
82 lines (72 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.9;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../../framework/MessageApp.sol";
// A HelloWorld example for basic cross-chain message passing with associate cross-chain token transfer
contract MsgExampleBasicTransfer is MessageApp {
using SafeERC20 for IERC20;
event MessageWithTransferReceived(address sender, address token, uint256 amount, uint64 srcChainId, bytes note);
event MessageWithTransferRefunded(address sender, address token, uint256 amount, bytes note);
// account, token -> balance
mapping(address => mapping(address => uint256)) public balances;
constructor(address _messageBus) MessageApp(_messageBus) {}
// called by user on source chain to send token with note to destination chain
function sendTokenWithNote(
address _dstContract,
address _token,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage,
bytes calldata _note,
MsgDataTypes.BridgeSendType _bridgeSendType
) external payable {
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
bytes memory message = abi.encode(msg.sender, _note);
sendMessageWithTransfer(
_dstContract,
_token,
_amount,
_dstChainId,
_nonce,
_maxSlippage,
message,
_bridgeSendType,
msg.value
);
}
// called by MessageBus on destination chain to receive message, record and emit info.
// the associated token transfer is guaranteed to have already been received
function executeMessageWithTransfer(
address, // srcContract
address _token,
uint256 _amount,
uint64 _srcChainId,
bytes memory _message,
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
(address sender, bytes memory note) = abi.decode((_message), (address, bytes));
balances[sender][_token] += _amount;
emit MessageWithTransferReceived(sender, _token, _amount, _srcChainId, note);
return ExecutionStatus.Success;
}
// called by MessageBus on source chain to handle message with failed token transfer
// the associated token transfer is guaranteed to have already been refunded
function executeMessageWithTransferRefund(
address _token,
uint256 _amount,
bytes calldata _message,
address // executor
) external payable override onlyMessageBus returns (ExecutionStatus) {
(address sender, bytes memory note) = abi.decode((_message), (address, bytes));
IERC20(_token).safeTransfer(sender, _amount);
emit MessageWithTransferRefunded(sender, _token, _amount, note);
return ExecutionStatus.Success;
}
// called by user on destination chain to withdraw tokens
function withdraw(address _token, uint256 _amount) external {
balances[msg.sender][_token] -= _amount;
IERC20(_token).safeTransfer(msg.sender, _amount);
}
}