@@ -167,8 +167,10 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
167
167
require (to != address (0 ), "ERC1155: transfer to the zero address " );
168
168
169
169
address operator = _msgSender ();
170
+ uint256 [] memory ids = _asSingletonArray (id);
171
+ uint256 [] memory amounts = _asSingletonArray (amount);
170
172
171
- _beforeTokenTransfer (operator, from, to, _asSingletonArray (id), _asSingletonArray (amount) , data);
173
+ _beforeTokenTransfer (operator, from, to, ids, amounts , data);
172
174
173
175
uint256 fromBalance = _balances[id][from];
174
176
require (fromBalance >= amount, "ERC1155: insufficient balance for transfer " );
@@ -180,6 +182,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
180
182
emit TransferSingle (operator, from, to, id, amount);
181
183
182
184
_doSafeTransferAcceptanceCheck (operator, from, to, id, amount, data);
185
+
186
+ _afterTokenTransfer (operator, from, to, ids, amounts, data);
183
187
}
184
188
185
189
/**
@@ -221,6 +225,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
221
225
emit TransferBatch (operator, from, to, ids, amounts);
222
226
223
227
_doSafeBatchTransferAcceptanceCheck (operator, from, to, ids, amounts, data);
228
+
229
+ _afterTokenTransfer (operator, from, to, ids, amounts, data);
224
230
}
225
231
226
232
/**
@@ -266,13 +272,17 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
266
272
require (to != address (0 ), "ERC1155: mint to the zero address " );
267
273
268
274
address operator = _msgSender ();
275
+ uint256 [] memory ids = _asSingletonArray (id);
276
+ uint256 [] memory amounts = _asSingletonArray (amount);
269
277
270
- _beforeTokenTransfer (operator, address (0 ), to, _asSingletonArray (id), _asSingletonArray (amount) , data);
278
+ _beforeTokenTransfer (operator, address (0 ), to, ids, amounts , data);
271
279
272
280
_balances[id][to] += amount;
273
281
emit TransferSingle (operator, address (0 ), to, id, amount);
274
282
275
283
_doSafeTransferAcceptanceCheck (operator, address (0 ), to, id, amount, data);
284
+
285
+ _afterTokenTransfer (operator, address (0 ), to, ids, amounts, data);
276
286
}
277
287
278
288
/**
@@ -304,6 +314,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
304
314
emit TransferBatch (operator, address (0 ), to, ids, amounts);
305
315
306
316
_doSafeBatchTransferAcceptanceCheck (operator, address (0 ), to, ids, amounts, data);
317
+
318
+ _afterTokenTransfer (operator, address (0 ), to, ids, amounts, data);
307
319
}
308
320
309
321
/**
@@ -322,8 +334,10 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
322
334
require (from != address (0 ), "ERC1155: burn from the zero address " );
323
335
324
336
address operator = _msgSender ();
337
+ uint256 [] memory ids = _asSingletonArray (id);
338
+ uint256 [] memory amounts = _asSingletonArray (amount);
325
339
326
- _beforeTokenTransfer (operator, from, address (0 ), _asSingletonArray (id), _asSingletonArray (amount) , "" );
340
+ _beforeTokenTransfer (operator, from, address (0 ), ids, amounts , "" );
327
341
328
342
uint256 fromBalance = _balances[id][from];
329
343
require (fromBalance >= amount, "ERC1155: burn amount exceeds balance " );
@@ -332,6 +346,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
332
346
}
333
347
334
348
emit TransferSingle (operator, from, address (0 ), id, amount);
349
+
350
+ _afterTokenTransfer (operator, from, address (0 ), ids, amounts, "" );
335
351
}
336
352
337
353
/**
@@ -365,6 +381,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
365
381
}
366
382
367
383
emit TransferBatch (operator, from, address (0 ), ids, amounts);
384
+
385
+ _afterTokenTransfer (operator, from, address (0 ), ids, amounts, "" );
368
386
}
369
387
370
388
/**
@@ -411,6 +429,35 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
411
429
bytes memory data
412
430
) internal virtual {}
413
431
432
+ /**
433
+ * @dev Hook that is called after any token transfer. This includes minting
434
+ * and burning, as well as batched variants.
435
+ *
436
+ * The same hook is called on both single and batched variants. For single
437
+ * transfers, the length of the `id` and `amount` arrays will be 1.
438
+ *
439
+ * Calling conditions (for each `id` and `amount` pair):
440
+ *
441
+ * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
442
+ * of token type `id` will be transferred to `to`.
443
+ * - When `from` is zero, `amount` tokens of token type `id` will be minted
444
+ * for `to`.
445
+ * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
446
+ * will be burned.
447
+ * - `from` and `to` are never both zero.
448
+ * - `ids` and `amounts` have the same, non-zero length.
449
+ *
450
+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
451
+ */
452
+ function _afterTokenTransfer (
453
+ address operator ,
454
+ address from ,
455
+ address to ,
456
+ uint256 [] memory ids ,
457
+ uint256 [] memory amounts ,
458
+ bytes memory data
459
+ ) internal virtual {}
460
+
414
461
function _doSafeTransferAcceptanceCheck (
415
462
address operator ,
416
463
address from ,
0 commit comments