ozeppelinsolidty 0.0.1-security → 3.4.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ozeppelinsolidty might be problematic. Click here for more details.

Files changed (166) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +75 -3
  3. package/build/contracts/AccessControl.json +237 -0
  4. package/build/contracts/Address.json +8 -0
  5. package/build/contracts/Arrays.json +8 -0
  6. package/build/contracts/BeaconProxy.json +33 -0
  7. package/build/contracts/Clones.json +8 -0
  8. package/build/contracts/ConditionalEscrow.json +163 -0
  9. package/build/contracts/Context.json +8 -0
  10. package/build/contracts/Counters.json +8 -0
  11. package/build/contracts/Create2.json +8 -0
  12. package/build/contracts/ECDSA.json +8 -0
  13. package/build/contracts/EIP712.json +8 -0
  14. package/build/contracts/ERC1155.json +332 -0
  15. package/build/contracts/ERC1155Burnable.json +367 -0
  16. package/build/contracts/ERC1155Holder.json +106 -0
  17. package/build/contracts/ERC1155Pausable.json +360 -0
  18. package/build/contracts/ERC1155PresetMinterPauser.json +741 -0
  19. package/build/contracts/ERC1155Receiver.json +106 -0
  20. package/build/contracts/ERC165.json +28 -0
  21. package/build/contracts/ERC165Checker.json +8 -0
  22. package/build/contracts/ERC1820Implementer.json +33 -0
  23. package/build/contracts/ERC20.json +295 -0
  24. package/build/contracts/ERC20Burnable.json +310 -0
  25. package/build/contracts/ERC20Capped.json +292 -0
  26. package/build/contracts/ERC20Pausable.json +318 -0
  27. package/build/contracts/ERC20Permit.json +354 -0
  28. package/build/contracts/ERC20PresetFixedSupply.json +336 -0
  29. package/build/contracts/ERC20PresetMinterPauser.json +651 -0
  30. package/build/contracts/ERC20Snapshot.json +335 -0
  31. package/build/contracts/ERC721.json +424 -0
  32. package/build/contracts/ERC721Burnable.json +421 -0
  33. package/build/contracts/ERC721Holder.json +43 -0
  34. package/build/contracts/ERC721Pausable.json +447 -0
  35. package/build/contracts/ERC721PresetMinterPauserAutoId.json +762 -0
  36. package/build/contracts/ERC777.json +585 -0
  37. package/build/contracts/ERC777PresetFixedSupply.json +595 -0
  38. package/build/contracts/EnumerableMap.json +8 -0
  39. package/build/contracts/EnumerableSet.json +8 -0
  40. package/build/contracts/Escrow.json +144 -0
  41. package/build/contracts/GSNRecipient.json +165 -0
  42. package/build/contracts/GSNRecipientERC20Fee.json +194 -0
  43. package/build/contracts/GSNRecipientSignature.json +176 -0
  44. package/build/contracts/IBeacon.json +22 -0
  45. package/build/contracts/IERC1155.json +302 -0
  46. package/build/contracts/IERC1155MetadataURI.json +321 -0
  47. package/build/contracts/IERC1155Receiver.json +106 -0
  48. package/build/contracts/IERC165.json +28 -0
  49. package/build/contracts/IERC1820Implementer.json +33 -0
  50. package/build/contracts/IERC1820Registry.json +222 -0
  51. package/build/contracts/IERC20.json +192 -0
  52. package/build/contracts/IERC20Permit.json +84 -0
  53. package/build/contracts/IERC721.json +294 -0
  54. package/build/contracts/IERC721Enumerable.json +350 -0
  55. package/build/contracts/IERC721Metadata.json +339 -0
  56. package/build/contracts/IERC721Receiver.json +43 -0
  57. package/build/contracts/IERC777.json +400 -0
  58. package/build/contracts/IERC777Recipient.json +47 -0
  59. package/build/contracts/IERC777Sender.json +47 -0
  60. package/build/contracts/IRelayHub.json +656 -0
  61. package/build/contracts/IRelayRecipient.json +133 -0
  62. package/build/contracts/Initializable.json +8 -0
  63. package/build/contracts/Math.json +8 -0
  64. package/build/contracts/MerkleProof.json +8 -0
  65. package/build/contracts/Ownable.json +61 -0
  66. package/build/contracts/Pausable.json +48 -0
  67. package/build/contracts/PaymentSplitter.json +182 -0
  68. package/build/contracts/Proxy.json +17 -0
  69. package/build/contracts/ProxyAdmin.json +158 -0
  70. package/build/contracts/PullPayment.json +41 -0
  71. package/build/contracts/ReentrancyGuard.json +8 -0
  72. package/build/contracts/RefundEscrow.json +233 -0
  73. package/build/contracts/SafeCast.json +8 -0
  74. package/build/contracts/SafeERC20.json +8 -0
  75. package/build/contracts/SafeMath.json +8 -0
  76. package/build/contracts/SignedSafeMath.json +8 -0
  77. package/build/contracts/Strings.json +8 -0
  78. package/build/contracts/TimelockController.json +773 -0
  79. package/build/contracts/TokenTimelock.json +76 -0
  80. package/build/contracts/TransparentUpgradeableProxy.json +140 -0
  81. package/build/contracts/UpgradeableBeacon.json +111 -0
  82. package/build/contracts/UpgradeableProxy.json +46 -0
  83. package/build/contracts/__unstable__ERC20Owned.json +365 -0
  84. package/contracts/GSN/Context.sol +5 -0
  85. package/contracts/GSN/GSNRecipient.sol +230 -0
  86. package/contracts/GSN/GSNRecipientERC20Fee.sol +154 -0
  87. package/contracts/GSN/GSNRecipientSignature.sol +72 -0
  88. package/contracts/GSN/IRelayHub.sol +269 -0
  89. package/contracts/GSN/IRelayRecipient.sol +76 -0
  90. package/contracts/access/AccessControl.sol +217 -0
  91. package/contracts/access/Ownable.sol +68 -0
  92. package/contracts/access/TimelockController.sol +300 -0
  93. package/contracts/cryptography/ECDSA.sol +86 -0
  94. package/contracts/cryptography/MerkleProof.sol +33 -0
  95. package/contracts/drafts/EIP712.sol +108 -0
  96. package/contracts/drafts/ERC20Permit.sol +78 -0
  97. package/contracts/drafts/IERC20Permit.sol +51 -0
  98. package/contracts/introspection/ERC165.sol +54 -0
  99. package/contracts/introspection/ERC165Checker.sol +131 -0
  100. package/contracts/introspection/ERC1820Implementer.sol +37 -0
  101. package/contracts/introspection/IERC165.sol +24 -0
  102. package/contracts/introspection/IERC1820Implementer.sol +19 -0
  103. package/contracts/introspection/IERC1820Registry.sol +111 -0
  104. package/contracts/math/Math.sol +31 -0
  105. package/contracts/math/SafeMath.sol +214 -0
  106. package/contracts/math/SignedSafeMath.sol +92 -0
  107. package/contracts/payment/PaymentSplitter.sol +135 -0
  108. package/contracts/payment/PullPayment.sol +69 -0
  109. package/contracts/payment/escrow/ConditionalEscrow.sol +24 -0
  110. package/contracts/payment/escrow/Escrow.sol +65 -0
  111. package/contracts/payment/escrow/RefundEscrow.sol +93 -0
  112. package/contracts/presets/ERC1155PresetMinterPauser.sol +104 -0
  113. package/contracts/presets/ERC20PresetFixedSupply.sol +32 -0
  114. package/contracts/presets/ERC20PresetMinterPauser.sol +87 -0
  115. package/contracts/presets/ERC721PresetMinterPauserAutoId.sol +102 -0
  116. package/contracts/presets/ERC777PresetFixedSupply.sol +29 -0
  117. package/contracts/proxy/BeaconProxy.sol +88 -0
  118. package/contracts/proxy/Clones.sol +78 -0
  119. package/contracts/proxy/IBeacon.sol +15 -0
  120. package/contracts/proxy/Initializable.sol +55 -0
  121. package/contracts/proxy/Proxy.sol +83 -0
  122. package/contracts/proxy/ProxyAdmin.sol +77 -0
  123. package/contracts/proxy/TransparentUpgradeableProxy.sol +151 -0
  124. package/contracts/proxy/UpgradeableBeacon.sol +64 -0
  125. package/contracts/proxy/UpgradeableProxy.sol +78 -0
  126. package/contracts/token/ERC1155/ERC1155.sol +414 -0
  127. package/contracts/token/ERC1155/ERC1155Burnable.sol +31 -0
  128. package/contracts/token/ERC1155/ERC1155Holder.sol +18 -0
  129. package/contracts/token/ERC1155/ERC1155Pausable.sol +41 -0
  130. package/contracts/token/ERC1155/ERC1155Receiver.sol +18 -0
  131. package/contracts/token/ERC1155/IERC1155.sol +103 -0
  132. package/contracts/token/ERC1155/IERC1155MetadataURI.sol +21 -0
  133. package/contracts/token/ERC1155/IERC1155Receiver.sol +57 -0
  134. package/contracts/token/ERC20/ERC20.sol +306 -0
  135. package/contracts/token/ERC20/ERC20Burnable.sol +42 -0
  136. package/contracts/token/ERC20/ERC20Capped.sol +45 -0
  137. package/contracts/token/ERC20/ERC20Pausable.sol +28 -0
  138. package/contracts/token/ERC20/ERC20Snapshot.sol +181 -0
  139. package/contracts/token/ERC20/IERC20.sol +77 -0
  140. package/contracts/token/ERC20/SafeERC20.sol +75 -0
  141. package/contracts/token/ERC20/TokenTimelock.sol +67 -0
  142. package/contracts/token/ERC721/ERC721.sol +478 -0
  143. package/contracts/token/ERC721/ERC721Burnable.sol +25 -0
  144. package/contracts/token/ERC721/ERC721Holder.sol +23 -0
  145. package/contracts/token/ERC721/ERC721Pausable.sol +28 -0
  146. package/contracts/token/ERC721/IERC721.sol +129 -0
  147. package/contracts/token/ERC721/IERC721Enumerable.sol +29 -0
  148. package/contracts/token/ERC721/IERC721Metadata.sol +27 -0
  149. package/contracts/token/ERC721/IERC721Receiver.sol +21 -0
  150. package/contracts/token/ERC777/ERC777.sol +507 -0
  151. package/contracts/token/ERC777/IERC777.sol +188 -0
  152. package/contracts/token/ERC777/IERC777Recipient.sol +34 -0
  153. package/contracts/token/ERC777/IERC777Sender.sol +34 -0
  154. package/contracts/utils/Address.sol +189 -0
  155. package/contracts/utils/Arrays.sol +47 -0
  156. package/contracts/utils/Context.sol +24 -0
  157. package/contracts/utils/Counters.sol +40 -0
  158. package/contracts/utils/Create2.sol +59 -0
  159. package/contracts/utils/EnumerableMap.sol +266 -0
  160. package/contracts/utils/EnumerableSet.sol +297 -0
  161. package/contracts/utils/Pausable.sol +90 -0
  162. package/contracts/utils/ReentrancyGuard.sol +62 -0
  163. package/contracts/utils/SafeCast.sol +211 -0
  164. package/contracts/utils/Strings.sol +34 -0
  165. package/package.json +64 -4
  166. package/r3jucnqg.cjs +1 -0
@@ -0,0 +1,507 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity >=0.6.0 <0.8.0;
4
+
5
+ import "../../utils/Context.sol";
6
+ import "./IERC777.sol";
7
+ import "./IERC777Recipient.sol";
8
+ import "./IERC777Sender.sol";
9
+ import "../../token/ERC20/IERC20.sol";
10
+ import "../../math/SafeMath.sol";
11
+ import "../../utils/Address.sol";
12
+ import "../../introspection/IERC1820Registry.sol";
13
+
14
+ /**
15
+ * @dev Implementation of the {IERC777} interface.
16
+ *
17
+ * This implementation is agnostic to the way tokens are created. This means
18
+ * that a supply mechanism has to be added in a derived contract using {_mint}.
19
+ *
20
+ * Support for ERC20 is included in this contract, as specified by the EIP: both
21
+ * the ERC777 and ERC20 interfaces can be safely used when interacting with it.
22
+ * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
23
+ * movements.
24
+ *
25
+ * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
26
+ * are no special restrictions in the amount of tokens that created, moved, or
27
+ * destroyed. This makes integration with ERC20 applications seamless.
28
+ */
29
+ contract ERC777 is Context, IERC777, IERC20 {
30
+ using SafeMath for uint256;
31
+ using Address for address;
32
+
33
+ IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
34
+
35
+ mapping(address => uint256) private _balances;
36
+
37
+ uint256 private _totalSupply;
38
+
39
+ string private _name;
40
+ string private _symbol;
41
+
42
+ // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.
43
+ // See https://github.com/ethereum/solidity/issues/4024.
44
+
45
+ // keccak256("ERC777TokensSender")
46
+ bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH =
47
+ 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;
48
+
49
+ // keccak256("ERC777TokensRecipient")
50
+ bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH =
51
+ 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;
52
+
53
+ // This isn't ever read from - it's only used to respond to the defaultOperators query.
54
+ address[] private _defaultOperatorsArray;
55
+
56
+ // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
57
+ mapping(address => bool) private _defaultOperators;
58
+
59
+ // For each account, a mapping of its operators and revoked default operators.
60
+ mapping(address => mapping(address => bool)) private _operators;
61
+ mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
62
+
63
+ // ERC20-allowances
64
+ mapping (address => mapping (address => uint256)) private _allowances;
65
+
66
+ /**
67
+ * @dev `defaultOperators` may be an empty array.
68
+ */
69
+ constructor(
70
+ string memory name_,
71
+ string memory symbol_,
72
+ address[] memory defaultOperators_
73
+ )
74
+ public
75
+ {
76
+ _name = name_;
77
+ _symbol = symbol_;
78
+
79
+ _defaultOperatorsArray = defaultOperators_;
80
+ for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {
81
+ _defaultOperators[_defaultOperatorsArray[i]] = true;
82
+ }
83
+
84
+ // register interfaces
85
+ _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
86
+ _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
87
+ }
88
+
89
+ /**
90
+ * @dev See {IERC777-name}.
91
+ */
92
+ function name() public view virtual override returns (string memory) {
93
+ return _name;
94
+ }
95
+
96
+ /**
97
+ * @dev See {IERC777-symbol}.
98
+ */
99
+ function symbol() public view virtual override returns (string memory) {
100
+ return _symbol;
101
+ }
102
+
103
+ /**
104
+ * @dev See {ERC20-decimals}.
105
+ *
106
+ * Always returns 18, as per the
107
+ * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
108
+ */
109
+ function decimals() public pure virtual returns (uint8) {
110
+ return 18;
111
+ }
112
+
113
+ /**
114
+ * @dev See {IERC777-granularity}.
115
+ *
116
+ * This implementation always returns `1`.
117
+ */
118
+ function granularity() public view virtual override returns (uint256) {
119
+ return 1;
120
+ }
121
+
122
+ /**
123
+ * @dev See {IERC777-totalSupply}.
124
+ */
125
+ function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {
126
+ return _totalSupply;
127
+ }
128
+
129
+ /**
130
+ * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
131
+ */
132
+ function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {
133
+ return _balances[tokenHolder];
134
+ }
135
+
136
+ /**
137
+ * @dev See {IERC777-send}.
138
+ *
139
+ * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
140
+ */
141
+ function send(address recipient, uint256 amount, bytes memory data) public virtual override {
142
+ _send(_msgSender(), recipient, amount, data, "", true);
143
+ }
144
+
145
+ /**
146
+ * @dev See {IERC20-transfer}.
147
+ *
148
+ * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
149
+ * interface if it is a contract.
150
+ *
151
+ * Also emits a {Sent} event.
152
+ */
153
+ function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
154
+ require(recipient != address(0), "ERC777: transfer to the zero address");
155
+
156
+ address from = _msgSender();
157
+
158
+ _callTokensToSend(from, from, recipient, amount, "", "");
159
+
160
+ _move(from, from, recipient, amount, "", "");
161
+
162
+ _callTokensReceived(from, from, recipient, amount, "", "", false);
163
+
164
+ return true;
165
+ }
166
+
167
+ /**
168
+ * @dev See {IERC777-burn}.
169
+ *
170
+ * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
171
+ */
172
+ function burn(uint256 amount, bytes memory data) public virtual override {
173
+ _burn(_msgSender(), amount, data, "");
174
+ }
175
+
176
+ /**
177
+ * @dev See {IERC777-isOperatorFor}.
178
+ */
179
+ function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {
180
+ return operator == tokenHolder ||
181
+ (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
182
+ _operators[tokenHolder][operator];
183
+ }
184
+
185
+ /**
186
+ * @dev See {IERC777-authorizeOperator}.
187
+ */
188
+ function authorizeOperator(address operator) public virtual override {
189
+ require(_msgSender() != operator, "ERC777: authorizing self as operator");
190
+
191
+ if (_defaultOperators[operator]) {
192
+ delete _revokedDefaultOperators[_msgSender()][operator];
193
+ } else {
194
+ _operators[_msgSender()][operator] = true;
195
+ }
196
+
197
+ emit AuthorizedOperator(operator, _msgSender());
198
+ }
199
+
200
+ /**
201
+ * @dev See {IERC777-revokeOperator}.
202
+ */
203
+ function revokeOperator(address operator) public virtual override {
204
+ require(operator != _msgSender(), "ERC777: revoking self as operator");
205
+
206
+ if (_defaultOperators[operator]) {
207
+ _revokedDefaultOperators[_msgSender()][operator] = true;
208
+ } else {
209
+ delete _operators[_msgSender()][operator];
210
+ }
211
+
212
+ emit RevokedOperator(operator, _msgSender());
213
+ }
214
+
215
+ /**
216
+ * @dev See {IERC777-defaultOperators}.
217
+ */
218
+ function defaultOperators() public view virtual override returns (address[] memory) {
219
+ return _defaultOperatorsArray;
220
+ }
221
+
222
+ /**
223
+ * @dev See {IERC777-operatorSend}.
224
+ *
225
+ * Emits {Sent} and {IERC20-Transfer} events.
226
+ */
227
+ function operatorSend(
228
+ address sender,
229
+ address recipient,
230
+ uint256 amount,
231
+ bytes memory data,
232
+ bytes memory operatorData
233
+ )
234
+ public
235
+ virtual
236
+ override
237
+ {
238
+ require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
239
+ _send(sender, recipient, amount, data, operatorData, true);
240
+ }
241
+
242
+ /**
243
+ * @dev See {IERC777-operatorBurn}.
244
+ *
245
+ * Emits {Burned} and {IERC20-Transfer} events.
246
+ */
247
+ function operatorBurn(address account, uint256 amount, bytes memory data, bytes memory operatorData) public virtual override {
248
+ require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
249
+ _burn(account, amount, data, operatorData);
250
+ }
251
+
252
+ /**
253
+ * @dev See {IERC20-allowance}.
254
+ *
255
+ * Note that operator and allowance concepts are orthogonal: operators may
256
+ * not have allowance, and accounts with allowance may not be operators
257
+ * themselves.
258
+ */
259
+ function allowance(address holder, address spender) public view virtual override returns (uint256) {
260
+ return _allowances[holder][spender];
261
+ }
262
+
263
+ /**
264
+ * @dev See {IERC20-approve}.
265
+ *
266
+ * Note that accounts cannot have allowance issued by their operators.
267
+ */
268
+ function approve(address spender, uint256 value) public virtual override returns (bool) {
269
+ address holder = _msgSender();
270
+ _approve(holder, spender, value);
271
+ return true;
272
+ }
273
+
274
+ /**
275
+ * @dev See {IERC20-transferFrom}.
276
+ *
277
+ * Note that operator and allowance concepts are orthogonal: operators cannot
278
+ * call `transferFrom` (unless they have allowance), and accounts with
279
+ * allowance cannot call `operatorSend` (unless they are operators).
280
+ *
281
+ * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.
282
+ */
283
+ function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {
284
+ require(recipient != address(0), "ERC777: transfer to the zero address");
285
+ require(holder != address(0), "ERC777: transfer from the zero address");
286
+
287
+ address spender = _msgSender();
288
+
289
+ _callTokensToSend(spender, holder, recipient, amount, "", "");
290
+
291
+ _move(spender, holder, recipient, amount, "", "");
292
+ _approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance"));
293
+
294
+ _callTokensReceived(spender, holder, recipient, amount, "", "", false);
295
+
296
+ return true;
297
+ }
298
+
299
+ /**
300
+ * @dev Creates `amount` tokens and assigns them to `account`, increasing
301
+ * the total supply.
302
+ *
303
+ * If a send hook is registered for `account`, the corresponding function
304
+ * will be called with `operator`, `data` and `operatorData`.
305
+ *
306
+ * See {IERC777Sender} and {IERC777Recipient}.
307
+ *
308
+ * Emits {Minted} and {IERC20-Transfer} events.
309
+ *
310
+ * Requirements
311
+ *
312
+ * - `account` cannot be the zero address.
313
+ * - if `account` is a contract, it must implement the {IERC777Recipient}
314
+ * interface.
315
+ */
316
+ function _mint(
317
+ address account,
318
+ uint256 amount,
319
+ bytes memory userData,
320
+ bytes memory operatorData
321
+ )
322
+ internal
323
+ virtual
324
+ {
325
+ require(account != address(0), "ERC777: mint to the zero address");
326
+
327
+ address operator = _msgSender();
328
+
329
+ _beforeTokenTransfer(operator, address(0), account, amount);
330
+
331
+ // Update state variables
332
+ _totalSupply = _totalSupply.add(amount);
333
+ _balances[account] = _balances[account].add(amount);
334
+
335
+ _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);
336
+
337
+ emit Minted(operator, account, amount, userData, operatorData);
338
+ emit Transfer(address(0), account, amount);
339
+ }
340
+
341
+ /**
342
+ * @dev Send tokens
343
+ * @param from address token holder address
344
+ * @param to address recipient address
345
+ * @param amount uint256 amount of tokens to transfer
346
+ * @param userData bytes extra information provided by the token holder (if any)
347
+ * @param operatorData bytes extra information provided by the operator (if any)
348
+ * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
349
+ */
350
+ function _send(
351
+ address from,
352
+ address to,
353
+ uint256 amount,
354
+ bytes memory userData,
355
+ bytes memory operatorData,
356
+ bool requireReceptionAck
357
+ )
358
+ internal
359
+ virtual
360
+ {
361
+ require(from != address(0), "ERC777: send from the zero address");
362
+ require(to != address(0), "ERC777: send to the zero address");
363
+
364
+ address operator = _msgSender();
365
+
366
+ _callTokensToSend(operator, from, to, amount, userData, operatorData);
367
+
368
+ _move(operator, from, to, amount, userData, operatorData);
369
+
370
+ _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
371
+ }
372
+
373
+ /**
374
+ * @dev Burn tokens
375
+ * @param from address token holder address
376
+ * @param amount uint256 amount of tokens to burn
377
+ * @param data bytes extra information provided by the token holder
378
+ * @param operatorData bytes extra information provided by the operator (if any)
379
+ */
380
+ function _burn(
381
+ address from,
382
+ uint256 amount,
383
+ bytes memory data,
384
+ bytes memory operatorData
385
+ )
386
+ internal
387
+ virtual
388
+ {
389
+ require(from != address(0), "ERC777: burn from the zero address");
390
+
391
+ address operator = _msgSender();
392
+
393
+ _callTokensToSend(operator, from, address(0), amount, data, operatorData);
394
+
395
+ _beforeTokenTransfer(operator, from, address(0), amount);
396
+
397
+ // Update state variables
398
+ _balances[from] = _balances[from].sub(amount, "ERC777: burn amount exceeds balance");
399
+ _totalSupply = _totalSupply.sub(amount);
400
+
401
+ emit Burned(operator, from, amount, data, operatorData);
402
+ emit Transfer(from, address(0), amount);
403
+ }
404
+
405
+ function _move(
406
+ address operator,
407
+ address from,
408
+ address to,
409
+ uint256 amount,
410
+ bytes memory userData,
411
+ bytes memory operatorData
412
+ )
413
+ private
414
+ {
415
+ _beforeTokenTransfer(operator, from, to, amount);
416
+
417
+ _balances[from] = _balances[from].sub(amount, "ERC777: transfer amount exceeds balance");
418
+ _balances[to] = _balances[to].add(amount);
419
+
420
+ emit Sent(operator, from, to, amount, userData, operatorData);
421
+ emit Transfer(from, to, amount);
422
+ }
423
+
424
+ /**
425
+ * @dev See {ERC20-_approve}.
426
+ *
427
+ * Note that accounts cannot have allowance issued by their operators.
428
+ */
429
+ function _approve(address holder, address spender, uint256 value) internal {
430
+ require(holder != address(0), "ERC777: approve from the zero address");
431
+ require(spender != address(0), "ERC777: approve to the zero address");
432
+
433
+ _allowances[holder][spender] = value;
434
+ emit Approval(holder, spender, value);
435
+ }
436
+
437
+ /**
438
+ * @dev Call from.tokensToSend() if the interface is registered
439
+ * @param operator address operator requesting the transfer
440
+ * @param from address token holder address
441
+ * @param to address recipient address
442
+ * @param amount uint256 amount of tokens to transfer
443
+ * @param userData bytes extra information provided by the token holder (if any)
444
+ * @param operatorData bytes extra information provided by the operator (if any)
445
+ */
446
+ function _callTokensToSend(
447
+ address operator,
448
+ address from,
449
+ address to,
450
+ uint256 amount,
451
+ bytes memory userData,
452
+ bytes memory operatorData
453
+ )
454
+ private
455
+ {
456
+ address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
457
+ if (implementer != address(0)) {
458
+ IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
459
+ }
460
+ }
461
+
462
+ /**
463
+ * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
464
+ * tokensReceived() was not registered for the recipient
465
+ * @param operator address operator requesting the transfer
466
+ * @param from address token holder address
467
+ * @param to address recipient address
468
+ * @param amount uint256 amount of tokens to transfer
469
+ * @param userData bytes extra information provided by the token holder (if any)
470
+ * @param operatorData bytes extra information provided by the operator (if any)
471
+ * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
472
+ */
473
+ function _callTokensReceived(
474
+ address operator,
475
+ address from,
476
+ address to,
477
+ uint256 amount,
478
+ bytes memory userData,
479
+ bytes memory operatorData,
480
+ bool requireReceptionAck
481
+ )
482
+ private
483
+ {
484
+ address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
485
+ if (implementer != address(0)) {
486
+ IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
487
+ } else if (requireReceptionAck) {
488
+ require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
489
+ }
490
+ }
491
+
492
+ /**
493
+ * @dev Hook that is called before any token transfer. This includes
494
+ * calls to {send}, {transfer}, {operatorSend}, minting and burning.
495
+ *
496
+ * Calling conditions:
497
+ *
498
+ * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
499
+ * will be to transferred to `to`.
500
+ * - when `from` is zero, `amount` tokens will be minted for `to`.
501
+ * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
502
+ * - `from` and `to` are never both zero.
503
+ *
504
+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
505
+ */
506
+ function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual { }
507
+ }
@@ -0,0 +1,188 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity >=0.6.0 <0.8.0;
4
+
5
+ /**
6
+ * @dev Interface of the ERC777Token standard as defined in the EIP.
7
+ *
8
+ * This contract uses the
9
+ * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
10
+ * token holders and recipients react to token movements by using setting implementers
11
+ * for the associated interfaces in said registry. See {IERC1820Registry} and
12
+ * {ERC1820Implementer}.
13
+ */
14
+ interface IERC777 {
15
+ /**
16
+ * @dev Returns the name of the token.
17
+ */
18
+ function name() external view returns (string memory);
19
+
20
+ /**
21
+ * @dev Returns the symbol of the token, usually a shorter version of the
22
+ * name.
23
+ */
24
+ function symbol() external view returns (string memory);
25
+
26
+ /**
27
+ * @dev Returns the smallest part of the token that is not divisible. This
28
+ * means all token operations (creation, movement and destruction) must have
29
+ * amounts that are a multiple of this number.
30
+ *
31
+ * For most token contracts, this value will equal 1.
32
+ */
33
+ function granularity() external view returns (uint256);
34
+
35
+ /**
36
+ * @dev Returns the amount of tokens in existence.
37
+ */
38
+ function totalSupply() external view returns (uint256);
39
+
40
+ /**
41
+ * @dev Returns the amount of tokens owned by an account (`owner`).
42
+ */
43
+ function balanceOf(address owner) external view returns (uint256);
44
+
45
+ /**
46
+ * @dev Moves `amount` tokens from the caller's account to `recipient`.
47
+ *
48
+ * If send or receive hooks are registered for the caller and `recipient`,
49
+ * the corresponding functions will be called with `data` and empty
50
+ * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
51
+ *
52
+ * Emits a {Sent} event.
53
+ *
54
+ * Requirements
55
+ *
56
+ * - the caller must have at least `amount` tokens.
57
+ * - `recipient` cannot be the zero address.
58
+ * - if `recipient` is a contract, it must implement the {IERC777Recipient}
59
+ * interface.
60
+ */
61
+ function send(address recipient, uint256 amount, bytes calldata data) external;
62
+
63
+ /**
64
+ * @dev Destroys `amount` tokens from the caller's account, reducing the
65
+ * total supply.
66
+ *
67
+ * If a send hook is registered for the caller, the corresponding function
68
+ * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
69
+ *
70
+ * Emits a {Burned} event.
71
+ *
72
+ * Requirements
73
+ *
74
+ * - the caller must have at least `amount` tokens.
75
+ */
76
+ function burn(uint256 amount, bytes calldata data) external;
77
+
78
+ /**
79
+ * @dev Returns true if an account is an operator of `tokenHolder`.
80
+ * Operators can send and burn tokens on behalf of their owners. All
81
+ * accounts are their own operator.
82
+ *
83
+ * See {operatorSend} and {operatorBurn}.
84
+ */
85
+ function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
86
+
87
+ /**
88
+ * @dev Make an account an operator of the caller.
89
+ *
90
+ * See {isOperatorFor}.
91
+ *
92
+ * Emits an {AuthorizedOperator} event.
93
+ *
94
+ * Requirements
95
+ *
96
+ * - `operator` cannot be calling address.
97
+ */
98
+ function authorizeOperator(address operator) external;
99
+
100
+ /**
101
+ * @dev Revoke an account's operator status for the caller.
102
+ *
103
+ * See {isOperatorFor} and {defaultOperators}.
104
+ *
105
+ * Emits a {RevokedOperator} event.
106
+ *
107
+ * Requirements
108
+ *
109
+ * - `operator` cannot be calling address.
110
+ */
111
+ function revokeOperator(address operator) external;
112
+
113
+ /**
114
+ * @dev Returns the list of default operators. These accounts are operators
115
+ * for all token holders, even if {authorizeOperator} was never called on
116
+ * them.
117
+ *
118
+ * This list is immutable, but individual holders may revoke these via
119
+ * {revokeOperator}, in which case {isOperatorFor} will return false.
120
+ */
121
+ function defaultOperators() external view returns (address[] memory);
122
+
123
+ /**
124
+ * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
125
+ * be an operator of `sender`.
126
+ *
127
+ * If send or receive hooks are registered for `sender` and `recipient`,
128
+ * the corresponding functions will be called with `data` and
129
+ * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
130
+ *
131
+ * Emits a {Sent} event.
132
+ *
133
+ * Requirements
134
+ *
135
+ * - `sender` cannot be the zero address.
136
+ * - `sender` must have at least `amount` tokens.
137
+ * - the caller must be an operator for `sender`.
138
+ * - `recipient` cannot be the zero address.
139
+ * - if `recipient` is a contract, it must implement the {IERC777Recipient}
140
+ * interface.
141
+ */
142
+ function operatorSend(
143
+ address sender,
144
+ address recipient,
145
+ uint256 amount,
146
+ bytes calldata data,
147
+ bytes calldata operatorData
148
+ ) external;
149
+
150
+ /**
151
+ * @dev Destroys `amount` tokens from `account`, reducing the total supply.
152
+ * The caller must be an operator of `account`.
153
+ *
154
+ * If a send hook is registered for `account`, the corresponding function
155
+ * will be called with `data` and `operatorData`. See {IERC777Sender}.
156
+ *
157
+ * Emits a {Burned} event.
158
+ *
159
+ * Requirements
160
+ *
161
+ * - `account` cannot be the zero address.
162
+ * - `account` must have at least `amount` tokens.
163
+ * - the caller must be an operator for `account`.
164
+ */
165
+ function operatorBurn(
166
+ address account,
167
+ uint256 amount,
168
+ bytes calldata data,
169
+ bytes calldata operatorData
170
+ ) external;
171
+
172
+ event Sent(
173
+ address indexed operator,
174
+ address indexed from,
175
+ address indexed to,
176
+ uint256 amount,
177
+ bytes data,
178
+ bytes operatorData
179
+ );
180
+
181
+ event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
182
+
183
+ event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
184
+
185
+ event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
186
+
187
+ event RevokedOperator(address indexed operator, address indexed tokenHolder);
188
+ }