|
@@ -167,8 +167,10 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
require(to != address(0), "ERC1155: transfer to the zero address");
|
|
|
|
|
|
address operator = _msgSender();
|
|
|
+ uint256[] memory ids = _asSingletonArray(id);
|
|
|
+ uint256[] memory amounts = _asSingletonArray(amount);
|
|
|
|
|
|
- _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
|
|
|
+ _beforeTokenTransfer(operator, from, to, ids, amounts, data);
|
|
|
|
|
|
uint256 fromBalance = _balances[id][from];
|
|
|
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
|
|
@@ -180,6 +182,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
emit TransferSingle(operator, from, to, id, amount);
|
|
|
|
|
|
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
|
|
|
+
|
|
|
+ _afterTokenTransfer(operator, from, to, ids, amounts, data);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -221,6 +225,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
emit TransferBatch(operator, from, to, ids, amounts);
|
|
|
|
|
|
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
|
|
|
+
|
|
|
+ _afterTokenTransfer(operator, from, to, ids, amounts, data);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -266,13 +272,17 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
require(to != address(0), "ERC1155: mint to the zero address");
|
|
|
|
|
|
address operator = _msgSender();
|
|
|
+ uint256[] memory ids = _asSingletonArray(id);
|
|
|
+ uint256[] memory amounts = _asSingletonArray(amount);
|
|
|
|
|
|
- _beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);
|
|
|
+ _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
|
|
|
|
|
|
_balances[id][to] += amount;
|
|
|
emit TransferSingle(operator, address(0), to, id, amount);
|
|
|
|
|
|
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
|
|
|
+
|
|
|
+ _afterTokenTransfer(operator, address(0), to, ids, amounts, data);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -304,6 +314,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
emit TransferBatch(operator, address(0), to, ids, amounts);
|
|
|
|
|
|
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
|
|
|
+
|
|
|
+ _afterTokenTransfer(operator, address(0), to, ids, amounts, data);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -322,8 +334,10 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
require(from != address(0), "ERC1155: burn from the zero address");
|
|
|
|
|
|
address operator = _msgSender();
|
|
|
+ uint256[] memory ids = _asSingletonArray(id);
|
|
|
+ uint256[] memory amounts = _asSingletonArray(amount);
|
|
|
|
|
|
- _beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
|
|
|
+ _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
|
|
|
|
|
|
uint256 fromBalance = _balances[id][from];
|
|
|
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
|
|
@@ -332,6 +346,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
}
|
|
|
|
|
|
emit TransferSingle(operator, from, address(0), id, amount);
|
|
|
+
|
|
|
+ _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -365,6 +381,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
}
|
|
|
|
|
|
emit TransferBatch(operator, from, address(0), ids, amounts);
|
|
|
+
|
|
|
+ _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -411,6 +429,35 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
|
|
bytes memory data
|
|
|
) internal virtual {}
|
|
|
|
|
|
+ /**
|
|
|
+ * @dev Hook that is called after any token transfer. This includes minting
|
|
|
+ * and burning, as well as batched variants.
|
|
|
+ *
|
|
|
+ * The same hook is called on both single and batched variants. For single
|
|
|
+ * transfers, the length of the `id` and `amount` arrays will be 1.
|
|
|
+ *
|
|
|
+ * Calling conditions (for each `id` and `amount` pair):
|
|
|
+ *
|
|
|
+ * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
|
|
|
+ * of token type `id` will be transferred to `to`.
|
|
|
+ * - When `from` is zero, `amount` tokens of token type `id` will be minted
|
|
|
+ * for `to`.
|
|
|
+ * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
|
|
|
+ * will be burned.
|
|
|
+ * - `from` and `to` are never both zero.
|
|
|
+ * - `ids` and `amounts` have the same, non-zero length.
|
|
|
+ *
|
|
|
+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
|
|
|
+ */
|
|
|
+ function _afterTokenTransfer(
|
|
|
+ address operator,
|
|
|
+ address from,
|
|
|
+ address to,
|
|
|
+ uint256[] memory ids,
|
|
|
+ uint256[] memory amounts,
|
|
|
+ bytes memory data
|
|
|
+ ) internal virtual {}
|
|
|
+
|
|
|
function _doSafeTransferAcceptanceCheck(
|
|
|
address operator,
|
|
|
address from,
|