-
Notifications
You must be signed in to change notification settings - Fork 17
/
InterchainTokenStandard.sol
110 lines (98 loc) · 5.07 KB
/
InterchainTokenStandard.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
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IInterchainTokenStandard } from '../interfaces/IInterchainTokenStandard.sol';
import { ITransmitInterchainToken } from '../interfaces/ITransmitInterchainToken.sol';
/**
* @title An example implementation of the IInterchainTokenStandard.
* @notice The is an abstract contract that needs to be extended with an ERC20 implementation. See `InterchainToken` for an example implementation.
*/
abstract contract InterchainTokenStandard is IInterchainTokenStandard {
/**
* @notice Getter for the tokenId used for this token.
* @dev Needs to be overwritten.
* @return tokenId_ The tokenId that this token is registerred under.
*/
function interchainTokenId() public view virtual returns (bytes32 tokenId_);
/**
* @notice Getter for the interchain token service.
* @dev Needs to be overwritten.
* @return service The address of the interchain token service.
*/
function interchainTokenService() public view virtual returns (address service);
/**
* @notice Implementation of the interchainTransfer method
* @dev We chose to either pass `metadata` as raw data on a remote contract call, or if no data is passed, just do a transfer.
* A different implementation could use metadata to specify a function to invoke, or for other purposes as well.
* @param destinationChain The destination chain identifier.
* @param recipient The bytes representation of the address of the recipient.
* @param amount The amount of token to be transferred.
* @param metadata Either empty, just to facilitate an interchain transfer, or the data to be passed for an interchain contract call with transfer
* as per semantics defined by the token service.
*/
function interchainTransfer(
string calldata destinationChain,
bytes calldata recipient,
uint256 amount,
bytes calldata metadata
) external payable {
address sender = msg.sender;
_beforeInterchainTransfer(msg.sender, destinationChain, recipient, amount, metadata);
ITransmitInterchainToken(interchainTokenService()).transmitInterchainTransfer{ value: msg.value }(
interchainTokenId(),
sender,
destinationChain,
recipient,
amount,
metadata
);
}
/**
* @notice Implementation of the interchainTransferFrom method
* @dev We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer.
* A different implementation could use metadata to specify a function to invoke, or for other purposes as well.
* @param sender The sender of the tokens. They need to have approved `msg.sender` before this is called.
* @param destinationChain The string representation of the destination chain.
* @param recipient The bytes representation of the address of the recipient.
* @param amount The amount of token to be transferred.
* @param metadata Either empty, just to facilitate an interchain transfer, or the data to be passed to an interchain contract call and transfer.
*/
function interchainTransferFrom(
address sender,
string calldata destinationChain,
bytes calldata recipient,
uint256 amount,
bytes calldata metadata
) external payable {
_spendAllowance(sender, msg.sender, amount);
_beforeInterchainTransfer(sender, destinationChain, recipient, amount, metadata);
ITransmitInterchainToken(interchainTokenService()).transmitInterchainTransfer{ value: msg.value }(
interchainTokenId(),
sender,
destinationChain,
recipient,
amount,
metadata
);
}
/**
* @notice A method to be overwritten that will be called before an interchain transfer. One can approve the tokenManager here if needed,
* to allow users for a 1-call transfer in case of a lock-unlock token manager.
* @param from The sender of the tokens. They need to have approved `msg.sender` before this is called.
* @param destinationChain The string representation of the destination chain.
* @param destinationAddress The bytes representation of the address of the recipient.
* @param amount The amount of token to be transferred.
* @param metadata Either empty, just to facilitate an interchain transfer, or the data to be passed to an interchain contract call and transfer.
*/
function _beforeInterchainTransfer(
address from,
string calldata destinationChain,
bytes calldata destinationAddress,
uint256 amount,
bytes calldata metadata
) internal virtual {}
/**
* @notice A method to be overwritten that will decrease the allowance of the `spender` from `sender` by `amount`.
* @dev Needs to be overwritten. This provides flexibility for the choice of ERC20 implementation used. Must revert if allowance is not sufficient.
*/
function _spendAllowance(address sender, address spender, uint256 amount) internal virtual;
}