-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathReferenceTokenTransferrer.sol
150 lines (137 loc) · 4.57 KB
/
ReferenceTokenTransferrer.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "contracts/lib/ConsiderationConstants.sol";
// prettier-ignore
import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
} from "contracts/interfaces/AbridgedTokenInterfaces.sol";
import { TokenTransferrerErrors } from "contracts/interfaces/TokenTransferrerErrors.sol";
contract ReferenceTokenTransferrer is TokenTransferrerErrors {
/**
* @dev Internal function to transfer ERC20 tokens from a given originator
* to a given recipient. Sufficient approvals must be set on the
* contract performing the transfer.
*
* @param token The ERC20 token to transfer.
* @param from The originator of the transfer.
* @param to The recipient of the transfer.
* @param amount The amount to transfer.
*/
function _performERC20Transfer(
address token,
address from,
address to,
uint256 amount
) internal {
if (token.code.length == 0) {
revert NoContract(token);
}
(bool ok, bytes memory data) = token.call(
abi.encodeWithSelector(
ERC20Interface.transferFrom.selector,
from,
to,
amount
)
);
// NOTE: revert reasons are not "bubbled up" at the moment
if (!ok) {
revert TokenTransferGenericFailure(token, from, to, 0, amount);
}
if (data.length != 0 && data.length >= 32) {
if (!abi.decode(data, (bool))) {
revert BadReturnValueFromERC20OnTransfer(
token,
from,
to,
amount
);
}
}
}
/**
* @dev Internal function to transfer an ERC721 token from a given
* originator to a given recipient. Sufficient approvals must be set on
* the contract performing the transfer.
*
* @param token The ERC721 token to transfer.
* @param from The originator of the transfer.
* @param to The recipient of the transfer.
* @param identifier The tokenId to transfer.
*/
function _performERC721Transfer(
address token,
address from,
address to,
uint256 identifier
) internal {
if (token.code.length == 0) {
revert NoContract(token);
}
ERC721Interface(token).transferFrom(from, to, identifier);
}
/**
* @dev Internal function to transfer ERC1155 tokens from a given
* originator to a given recipient. Sufficient approvals must be set on
* the contract performing the transfer and contract recipients must
* implement onReceived to indicate that they are willing to accept the
* transfer.
*
* @param token The ERC1155 token to transfer.
* @param from The originator of the transfer.
* @param to The recipient of the transfer.
* @param identifier The id to transfer.
* @param amount The amount to transfer.
*/
function _performERC1155Transfer(
address token,
address from,
address to,
uint256 identifier,
uint256 amount
) internal {
if (token.code.length == 0) {
revert NoContract(token);
}
ERC1155Interface(token).safeTransferFrom(
from,
to,
identifier,
amount,
""
);
}
/**
* @dev Internal function to transfer ERC1155 tokens from a given
* originator to a given recipient. Sufficient approvals must be set on
* the contract performing the transfer and contract recipients must
* implement onReceived to indicate that they are willing to accept the
* transfer.
*
* @param token The ERC1155 token to transfer in batch.
* @param from The originator of the transfer batch.
* @param to The recipient of the transfer batch.
* @param identifiers The ids to transfer.
* @param amounts The amounts to transfer.
*/
function _performERC1155BatchTransfer(
address token,
address from,
address to,
uint256[] memory identifiers,
uint256[] memory amounts
) internal {
if (token.code.length == 0) {
revert NoContract(token);
}
ERC1155Interface(token).safeBatchTransferFrom(
from,
to,
identifiers,
amounts,
""
);
}
}