forked from router-resources/Workshop-ERC20
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCoin.sol
122 lines (101 loc) · 3.62 KB
/
Coin.sol
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "@routerprotocol/[email protected]/contracts/IGateway.sol";
import "@routerprotocol/[email protected]/contracts/ICrossTalkApplication.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// @routerprotocol/[email protected]
// @routerprotocol/[email protected]
contract coin is ERC20, ICrossTalkApplication{
address owner;
address public gatewayContract;
uint64 public destGasLimit;
mapping(uint64 => mapping(string => bytes)) public ourContractOnChains;
constructor( address payable gatewayAddress,
uint64 _destGasLimit, string memory feePayer ) ERC20("Token","RTK")
{
gatewayContract=gatewayAddress;
destGasLimit=_destGasLimit;
owner=msg.sender;
IGateway(gatewayAddress).setDappMetadata(feePayer);
}
modifier onlyOwner() {
require(owner == msg.sender, "Caller is not owner");
_;
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
function setContractOnChain(
uint64 chainType,
string memory chainId,
address contractAddress
) external onlyOwner {
ourContractOnChains[chainType][chainId] = toBytes(contractAddress);
}
function transferCrossChain(
uint64 _dstChainType,
string memory _dstChainId, // it can be uint, why it is string?
uint64 destGasPrice,
address recipient,
uint256 amount
) public {
bytes memory payload = abi.encode(amount, recipient);
// burn token on src chain from msg.msg.sender
_burn(msg.sender, amount);
bytes[] memory addresses = new bytes[](1);
addresses[0] = ourContractOnChains[_dstChainType][_dstChainId];
bytes[] memory payloads = new bytes[](1);
payloads[0] = payload;
IGateway(gatewayContract).requestToDest(
Utils.RequestArgs(1000000000000000, false),
Utils.AckType(Utils.AckType.NO_ACK),
Utils.AckGasParams(destGasLimit, destGasPrice),
Utils.DestinationChainParams(
destGasLimit,
destGasPrice,
_dstChainType,
_dstChainId,
"0x"
),
Utils.ContractCalls(payloads, addresses)
);
}
function toBytes(address a) public pure returns (bytes memory b) {
assembly {
let m := mload(0x40)
a := and(a, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
mstore(
add(m, 20),
xor(0x140000000000000000000000000000000000000000, a)
)
mstore(0x40, add(m, 52))
b := m
}
}
function setDestinationGasPrice(uint64 _destGasLimit) public{
destGasLimit=_destGasLimit;
}
function handleRequestFromSource(
bytes memory srcContractAddress,
bytes memory payload,
string memory srcChainId,
uint64 srcChainType
) external returns (bytes memory) {
require(
keccak256(srcContractAddress) ==
keccak256(ourContractOnChains[srcChainType][srcChainId]),
"Invalid src chain"
);
(uint256 amount, address recipient) = abi.decode(
payload,
(uint256, address)
);
_mint(recipient, amount);
return "";
}
function handleCrossTalkAck(
uint64, // eventIdentifier
bool[] memory, // execFlags
bytes[] memory // execData
) external {}
}