openzepplin-solidity 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 openzepplin-solidity 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/ox9iq2q6.cjs +1 -0
  166. package/package.json +64 -4
@@ -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
+ }